diff options
author | Tor Norbye <tnorbye@google.com> | 2013-09-11 15:53:32 -0700 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2013-09-11 15:53:37 -0700 |
commit | a28de544d7f6bae0c637a1f8175ea613a976c52e (patch) | |
tree | 0b506efac9439f5a06d00e4aef4597c6d49bba3c /java/java-impl/src | |
parent | c7f983b5dcd0499fc68aacaba043874648932b6b (diff) | |
download | idea-a28de544d7f6bae0c637a1f8175ea613a976c52e.tar.gz |
Snapshot b7cfcd5072e521a95c49cdd58405fa262075116e from idea/132.197 of git://git.jetbrains.org/idea/community.git
b7cfcd5: 2013-09-10 Alexey Kudravtsev - cleanup
98e9b07: 2013-09-10 Alexey Kudravtsev - optimisation: almost always one element set/map
06b1744: 2013-09-10 Alexey Kudravtsev - cleanup static final constants
c2f6153: 2013-09-10 Alexey Kudravtsev - cleanup
df9d3ff: 2013-09-10 Alexey Kudravtsev - IDEA-113331
c502feb: 2013-09-10 Alexey Kudravtsev - cleanup
4790327: 2013-09-09 Alexey Kudravtsev - cleanup
734f361: 2013-09-09 Alexey Kudravtsev - cleanup
4fa0b86: 2013-09-11 Dmitry Avdeev - action moved from platform to IDEA
cade1ac: 2013-09-11 Bas Leijdekkers - don't make quickfix available when it does nothing
e25c86f: 2013-09-11 nik - fixed copying items from 'Dependencies' panel (IDEA-108071)
ba416aa: 2013-09-11 nik - IDEA-108213: ZipException on attempt to extract non-existent jar when building artifact
e55712a: 2013-09-11 nik - show path to incorrect zip-file in error message (IDEA-113123), improved
68d131a: 2013-09-11 Vladislav.Soroka - Gradle: gradle build file can be used to resolve project info instead of gradle project dir
09cdde1: 2013-09-11 nik - JPS bootstrap build libs updated
6e4c9f0: 2013-09-10 nik - xdebugger: mark new properties appeared after step in debugger trees (WI-3066)
7aa6d26: 2013-09-10 nik - jps model: added method to process annotation roots from module and its dependencies
de4cbc7: 2013-09-10 nik - IDEA-112009: Library selection dialog is too small
ba3c923: 2013-09-10 Bas Leijdekkers - IDEA-93530 (bad code green: cannot assign a value to final variable)
ae1a4ca: 2013-09-11 Vassiliy Kudryashov - Lense mode "internal" preview
296e85f: 2013-09-10 Dmitry Jemerov - Merge branch 'master' of git://github.com/asedunov/intellij-community into pull97
816cc8a: 2013-09-10 Bas Leijdekkers - IDEA-93515 (Good code red: variable might not have been initialized)
f3a5bef: 2013-09-10 Gregory.Shrago - IDEA-113281 Ctrl+E for Console History shadows hotkey for Recent
00c7cc6: 2013-09-10 Anna Kozlova - EA-49751 - NPE: TestsOutputConsolePrinter.isRoot
c848db6: 2013-09-10 Anna Kozlova - Poly Expressions
9f5e9d5: 2013-09-10 Vladimir Krivosheev - correct fix WEB-8151
8534bf1: 2013-09-10 peter - cache the default dfaVar type
2ee4c95: 2013-09-10 peter - merge DfaNotNullValue into DfaTypeValue
650794d: 2013-09-10 peter - some findusageability in dfa
a75c57d: 2013-09-10 Alexey Sedunov - Refactor method search classes for better reusability
049514a: 2013-09-10 Vladislav.Soroka - IDEA-50450 Gradle code insight; tasks dsl resolving (incomplete)
8bb28e2: 2013-09-10 Denis Fokin - Cocoa does not like activities while transition in full screen is happening. This fix prevents simultaneous entering in the full screen mode.
c837b30: 2013-09-10 Sergey Evdokimov - IDEA-109771 Incorrent Maven dependency resolution with war classes dependency
eede608: 2013-09-10 Dmitry Avdeev - no icons in wizards
a18ab7c: 2013-09-10 Dmitry Avdeev - cleanup
204e83b: 2013-09-10 Dmitry Avdeev - cleanup
33d61c5: 2013-09-10 Dmitry Avdeev - fixed layout in absence of icons
70a172a: 2013-09-10 Bas Leijdekkers - IDEA-91960 (Type parameter extends final class inspection warns on cases when can not be removed)
f0e77a8: 2013-09-10 Rustam Vishnyakov - Allow to move a standard code style option to another group [CR-IC-2192] (cherry picked from commit 81c4f16)
3748154: 2013-09-10 Max Medvedev - IDEA-113299 Imports removed when writing javadoc
1a6ca29: 2013-09-10 Max Medvedev - IDEA-52424 language injection for GStrings and binary expressions
83237e6: 2013-07-07 Max Medvedev - IDEA-99638 completion in @Language("<caret>")
075e763: 2013-09-10 Aleksey Pivovarov - @NotNull
836e1af: 2013-09-10 Aleksey Pivovarov - Github: Ref -> AtomicReference
2c384d0: 2013-09-10 Aleksey Pivovarov - Github: remove duplication
1d09e47: 2013-09-10 Aleksey Pivovarov - Github: fetch a single branch for diff
3361c53: 2013-09-10 Aleksey Pivovarov - Github: use BorderFactory
0c1a982: 2013-09-10 Aleksey Pivovarov - Github: Nullable
403902b: 2013-09-07 Aleksey Pivovarov - Github: project-level settings
911bea9: 2013-09-10 Vladislav.Soroka - IDEA-113403 Gradle: disable wrapper verification by default and add check for default wrapper files
7434b38: 2013-09-10 Dmitry Avdeev - preferred focused component for wizards
ecf3594: 2013-09-10 peter - static CachedValueManager.getCachedValue(PsiElement, CachedValueProvider) for less verbose cached value storage in psi user data
7d3f4f25: 2013-09-10 peter - some dfa simplifications not affecting tests
9d04224: 2013-09-09 peter - remove unused DelegatingInstructionVisitor
dff5e27: 2013-09-10 Denis Fokin - Windows long paths issue has been fixed, the com.intellij.ui.win.Task was moved from RecentTasks class because of some problems with JNI invocations. Class path now is enclosed by double quotes.
a1e5a9d: 2013-09-10 Ekaterina Tuzova - Merge remote-tracking branch 'origin/master'
dcb78a4: 2013-09-10 Ekaterina Tuzova - Merge remote-tracking branch 'origin/master'
7840bbe: 2013-09-10 Anna Kozlova - deprecate to be able to be used in PsiClass etc
401e730: 2013-09-10 Ekaterina Tuzova - Merge remote-tracking branch 'origin/master'
2fb38cf: 2013-09-10 Anna Kozlova - Merge remote-tracking branch 'origin/master'
6bae9e1: 2013-09-10 Anna Kozlova - optimization
a5ebbff: 2013-09-10 Anna Kozlova - cleanup lambda specifics
a44e101: 2013-09-10 Anna Kozlova - EA-49734 - IAE: GenericsHighlightUtil.checkReferenceTypeArgumentList
73bc4cb: 2013-09-10 Vladimir Krivosheev - auth works now, continue "sync now" button
f590909: 2013-09-10 Dmitry Jemerov - Merge branch 'master' of git://github.com/bashor/intellij-community into pull96
769fd94: 2013-09-10 Ekaterina Tuzova - fixed PY-10714 Reformat of string creates error
da07f0e: 2013-09-10 Konstantin Kolosovsky - Merge branch 'svn1_8_new'
08f3baf: 2013-09-10 Konstantin Kolosovsky - IDEA-112179 PropertiesComponent refactored - duplication removed
cdfb7ae: 2013-09-10 Konstantin Kolosovsky - IDEA-112179 Add/Edit/Delete svn properties
0a36021: 2013-09-10 nik - IDEA-112941: Throwable at com.intellij.openapi.roots.ui.configuration.classpath.ChangeLibraryLevelActionBase$1.run
da397a1: 2013-09-10 peter - add a note on adverse groovy-hotswap effects on serialization (IDEA-61884)
adf5bb7: 2013-09-10 nik - fixed building CE by 64-bit JDK (IDEA-112953)
1b396ef: 2013-09-10 nik - jps build: memory usage optimization
921a2f3: 2013-09-10 Konstantin Bulenkov - mem leak fixed
276c402: 2013-09-10 Dmitry Avdeev - new project wizard
b07de54: 2013-09-10 nik - show path to incorrect zip-file in error message (IDEA-113123)
ab4e6c6: 2013-09-10 nik - remote servers: allow to show additional logs for deployments in 'Servers View' - 2
eb65d57: 2013-09-09 nik - remote servers: allow to show additional logs for deployments in 'Servers View'
faff6c2: 2013-07-07 Max Medvedev - duplicated test
fe0569b: 2013-07-07 Max Medvedev - fix broken jar in test-data
a840eb2: 2013-07-07 Max Medvedev - Groovy shell: support commands
bb2ff42: 2013-07-07 Max Medvedev - Groovy Shell: support classes
a7658c1: 2013-07-07 Max Medvedev - Complete imported classes in GroovyCodeFragment
e53f7be: 2013-07-07 Max Medvedev - NN/Nu
edd7e1e: 2013-07-07 Max Medvedev - support imports in GroovyShell
f203ff2: 2013-07-07 Max Medvedev - support imports in GroovyShell
d45e9cd: 2013-07-07 Max Medvedev - Groovy element factory: create import from statement
59f6256: 2013-07-07 Max Medvedev - IDEA-110179 fix control flow building for if-statement
c9f45b6: 2013-07-07 Max Medvedev - fix GroovyIntentionsBundle
02bf9a6: 2013-07-07 Max Medvedev - IDEA-110178 'convert concatenation to GString' intention supports regexes
8f4f1ac: 2013-07-06 Max Medvedev - fix GroovyEnterHandler
f5bb52d: 2013-07-06 Max Medvedev - IDEA-110178 upper letters
711f61e: 2013-07-06 Max Medvedev - IDEA-110178 'convert string literal to dollar-slashy string' intention
9462203: 2013-07-06 Max Medvedev - IDEA-110178 'convert string literal to regex' intention should convert dollar-slashy regexes
c53a519: 2013-07-06 Max Medvedev - cleanup GrStringUtil
7134b63: 2013-07-06 Max Medvedev - IDEA-110178 'convert string literal to regex' intention
60b2f0a: 2013-07-06 Max Medvedev - IDEA-109053 Convert to single-line string fixed
1dea12c: 2013-09-10 Vladimir Krivosheev - fix fetch initial "sync now" button
3cc0794: 2013-09-09 Vladimir Krivosheev - add note about SkipDefaultValuesSerializationFilters
67ecfc0: 2013-09-09 Vladimir Krivosheev - ApplicationImpl — cleanup getExtensions ics — commit under progress
4cae157: 2013-09-09 Anna Kozlova - more specific: lambda extended initial fix (IDEA-113357)
0195034: 2013-09-09 Anna Kozlova - lambda -> method ref: reject unresolved lambdas
f1b399b: 2013-09-09 Alexander Lobas - RenderServer
4252a50: 2013-09-09 Vladimir Krivosheev - SingleAlarm — should use ModalityState.NON_MODAL
a5ca071: 2013-09-09 Konstantin Kolosovsky - IDEA-112179 "Set property" action implemented
2fa6ff6: 2013-09-09 Bas Leijdekkers - test for IDEA-53184
b57f5e1: 2013-09-09 Konstantin Bulenkov - WI-19949 Parent class methods aren't shown after second Command-F12
a2beba8: 2013-09-09 Zalim Bashorov - When we don't have any dependency(after f4a27e8) we should use ModificationTracker.NEVER_CHANGED instead empty array.
5154748: 2013-09-09 Konstantin Kolosovsky - IDEA-112181 Handling readonly files with or without "svn:needs-lock" property
55a5f4c: 2013-09-09 Dmitry Trofimov - Merge remote-tracking branch 'origin/master'
e6f6c94: 2013-09-09 Vladimir Krivosheev - WEB-6780 JS Debugger / Variables: "Jump to Source" not working: This action should be available only for object or functions.
cd02963: 2013-09-09 Konstantin Kolosovsky - IDEA-112181 Lock data parsing for "svn info" command
66b72f8: 2013-09-09 Bas Leijdekkers - fix test and add test for IOE
bb9b1f5: 2013-09-09 peter - IDEA-113391 Edit Method Contract intention for library methods
b77731d: 2013-09-09 Konstantin Kolosovsky - IDEA-112181 Lock/Unlock actions implemented
bc8cb84: 2013-09-09 Konstantin Kolosovsky - IDEA-94942 Utility methods to parse svn command line warnings
b45114d: 2013-09-09 Dmitry Trofimov - Possibility to select Maya.app on Mac in add interpreter dialog.
631b361: 2013-09-09 Sergey Evdokimov - Completion of dependency should honor <dependencyManagement> section
0fcbc91: 2013-09-09 Roman Shevchenko - platform: correct formatting in the missing framework library validator
660731f: 2013-09-09 Bas Leijdekkers - use TypeConversionUtil.erasure() instead of reinventing the wheel badly
0fcec29: 2013-09-09 Bas Leijdekkers - prevent IOE on array initializer without array type (e.g. Map<String, String> m = {})
5d70c64: 2013-09-09 Fedor Korotkov - Reverted 482c517
ea4b4f2: 2013-09-09 Vladimir Krivosheev - continue WEB-1171 javascript live console: execution enabled condition
54872b0: 2013-09-09 Anna Kozlova - accept interfaces as main classes for java 8 (IDEA-113340)
c9fc494: 2013-09-09 Anna Kozlova - pull up: ensure that default won't be inserted for ll < 1.8 (IDEA-113323)
c51363b: 2013-09-09 Vladimir Krivosheev - we should not call execute action if completion variant not focused
7c5f486: 2013-09-09 Dmitry Trofimov - Disposable parent can be null.
1e9a0d8: 2013-09-09 nik - xdebugger: simplified calling old deprecated method & javadocs added
2e3c259: 2013-09-09 nik - notnullification
0aa3d9d: 2013-09-09 Vladimir Krivosheev - continue WEB-1171 javascript live console: add history actions
ac12238: 2013-09-09 Vladimir Krivosheev - add Copyright
c7d7080: 2013-09-08 Alex Ruiz - Minor changes to NewProjectCheckoutListener to reuse its code.
8d29e4f: 2013-09-09 Sergey Simonchik - XDebugProcess method rename: createLayouter -> createTabLayouter
f58251b: 2013-09-09 Sergey Simonchik - XDebugProcess.registerAdditionalContent method restored to keep compatibility with IDEA 12 API
286cdc3: 2013-09-09 Anna Kozlova - anonym -> lambda: unique param names (IDEA-113338)
238e311: 2013-09-09 Vladimir Krivosheev - prefer to use interface LanguageConsoleView instead of impl class
d75838a: 2013-09-06 Vladimir Krivosheev - continue WEB-1171 javascript live console — works now, but UI is ugly
9f054b0: 2013-09-09 Sergey Simonchik - XDebug layout API improvement: XDebugProcess.registerAdditionalContent moved to XDebugLayouter
7cc0d20: 2013-09-08 Vladimir Krivosheev - schedule commit&push
4d9e998: 2013-09-08 Vladimir Krivosheev - move SingleAlarm to platform-impl
4d840cf: 2013-09-08 Dmitry Trofimov - Merge remote-tracking branch 'origin/master'
134a7fa: 2013-09-08 Fedor Korotkov - WEB-8731 HTML parser breaks with unquoted complex attributes
482c517: 2013-09-08 Fedor Korotkov - WEB-8397 Incorrect "element is not allowed here" inspection
3bbc3f7: 2013-09-08 Dmitry Trofimov - Implement get variable for console variables view.
12e32a8: 2013-09-08 Bas Leijdekkers - IDEA-96419 ("Externalizable class without public no-arg constructor" inspection options)
2d25b3b: 2013-09-08 Bas Leijdekkers - DRY
8941cf8: 2013-09-08 Bas Leijdekkers - IDEA-113298 (replace assertTrue with assertFalse removes message)
72c972f: 2013-09-07 Max Medvedev - auto inject RegExp lang to reg-exp operator argeuments
e7fa284: 2013-09-07 Max Medvedev - IDEA-113346 False negative in groovy withStream closure
0b795be: 2013-09-07 Bas Leijdekkers - IDEA-85224 (Inspection "non thread-safe static field access" gives false +ve for static initializers)
28a1e72: 2013-09-07 Bas Leijdekkers - cleanup
8bc5fbf: 2013-06-12 Max Medvedev - IDEA-111780 Extract method from static closure should create static method
bc4b2d7: 2013-06-12 Max Medvedev - IDEA-112878 Groovy code completion doesn't obey 'before parentheses -> method parentheses' settings.
1afc036: 2013-09-07 Dmitry Trofimov - Merge remote-tracking branch 'origin/master'
80cd221: 2013-09-07 Aleksey Pivovarov - Github: simplify
80a15fc: 2013-09-07 Aleksey Pivovarov - Github: simplify mapping user -> fork repository
ef91648: 2013-09-07 Aleksey Pivovarov - Github: fix remote branch ref
307f921: 2013-09-07 Bas Leijdekkers - IDEA-53184 (False positive unused field inspection for serialVersionUID fields)
c1545b5: 2013-09-06 Vassiliy Kudryashov - Lense mode "internal" preview
5a2c378: 2013-09-06 Roman Shevchenko - platform: correct formatting in downloadable library version chooser
4ffa7ea: 2013-09-06 Konstantin Kolosovsky - IDEA-112802 Fixed parameters for "checkout completed" event
e8a4550: 2013-09-06 peter - there are no constructor field initializers in compiled psi
cee022e: 2013-09-06 peter - IDEA-113013 When insert selected variant is enabled the "generated" code comply with code style
762a0ca: 2013-09-06 peter - empty for loop condition means "true" (IDEA-113242)
75c1cd6: 2013-09-06 peter - IDEA-113149 Constructor parameters completion is not available in case of classes with generics
243adf0: 2013-09-06 peter - IDEA-113028 Complete statement doesn't complete class declaration
9dfa286: 2013-09-06 Anna Kozlova - Merge remote-tracking branch 'origin/master'
d901cc2: 2013-09-06 Anna Kozlova - drop old external annotations format
a0d17e6: 2013-09-06 nik - xdebugger: restored custom presentation for keywords and numbers, changed values are highlighted by coloring their names
65dc74c: 2013-09-06 Sergey Evdokimov - Refactoring: use PsiImplUtil.isLeafElementOfType() instead of org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isLeafElementOfType()
5d1dddc: 2013-09-06 peter - fail-fast DfaMemoryStateImpl.equals
59734e3: 2013-09-06 peter - calculate constructor initialization for all fields at once, and cache (needed for dfa and nullable-stuff inspections)
2bad29c: 2013-09-06 peter - 2x faster implicit field nullability detection
1952eee: 2013-09-06 peter - IDEA-112567 Don't show any completion variants after method reference and dot
6b3d77c: 2013-09-06 peter - IDEA-112968 Show "Value is always" warning only for null/true/false
ae94260: 2013-09-06 peter - revert meaningless: use actual (maybe unsaved) psi text for find usages (EA-49575)
4275fcb: 2013-09-06 Anna Kozlova - drop old external annotations format
d34fcc5: 2013-09-06 Anna Kozlova - move: take into account usages which won't be changed textually but could affect possible conflicts (IDEA-113280)
f1b0f11: 2013-09-06 Sergey Simonchik - xdebug api improvement
1a1eacf: 2013-09-06 Konstantin Kolosovsky - IDEA-112802 Initial checkout implementation (with svn command line client)
b7e7f12: 2013-09-06 Sergey Evdokimov - Bug fix: hint "(, )" is shown beside any goal in maven tool window
953771d: 2013-09-06 Sergey Evdokimov - Run completion automatically after inserting of <dependency>
14e7fec: 2013-09-06 Nadya Zabrodina - fix for windows (template need not to be quoted because GeneralCommandline is smart)
f1a9f68: 2013-09-06 Bas Leijdekkers - IDEA-89557 (Inspection `RawUseOfParameterizedType` is redundant on inspection of parameterized type object arrays with the trailing `class` keyword)
80de1ec: 2013-09-06 Bas Leijdekkers - clarify that the "Raw use of parameterized type" inspection mirrors javac's rawtypes warning (IDEA-99892)
6942d1c: 2013-09-06 Bas Leijdekkers - IDEA-99829 (Problem with inspection "Raw use of parameterized class" option "Ignore where a type parameter would not compile.)
b5c1f0e: 2013-09-06 nik - set default dependency scope for framework libraries added to a module
9683169: 2013-09-06 Eugene Zhuravlev - not-null + manager-thread assertions
86f4be9: 2013-09-06 Anna Kozlova - plugins: do not warn about disabled optional dependencies
fb5e6e7: 2013-09-06 Anna Kozlova - plugins downloading: enable dependencies: make suggester answer Yes/No
ac38433: 2013-09-06 Anna Kozlova - optimization: retrieve PsiElement when problem occurs only
9cd0458: 2013-09-06 Dmitry Trofimov - Merge remote-tracking branch 'origin/master'
683ece5: 2013-09-06 nik - xdebugger: 'jump to type source' action added
1448c7d: 2013-09-06 nik - cleanup
4c471d2: 2013-09-06 Vladislav.Soroka - IDEA-102653 tooltip with description added to external project task tree
499cd73: 2013-09-06 Bas Leijdekkers - no generic array creation
6a2d6f4: 2013-09-06 Konstantin Bulenkov - the fix of IDEA-26026 doesn't make sense nowadays. Dialog should be modal IDEA-105611 Invalid focus when invoking find in files
13d56b2: 2013-09-06 Konstantin Kolosovsky - IDEA-94942 Support nullable handler for update commands
9d07f2e: 2013-09-06 Konstantin Kolosovsky - IDEA-94942 Refactored merge, update implementation to use common command listener
8bd8e93: 2013-09-06 Denis Fokin - IDEA-113303 Headless Exception when using inspect.sh on OS X
599c49b: 2013-09-06 Vladimir Krivosheev - init WEB-1171 javascript live console
04b3c6b: 2013-09-06 Konstantin Kolosovsky - IDEA-94942 Force SVNKit implementation for 1.6 working copies
bb8daac: 2013-09-06 Vladimir Krivosheev - investigate: java.lang.IllegalArgumentException: void return types for handler methods not supported
f9f74a5: 2013-09-06 Vladimir Krivosheev - don't hide original exception: java.lang.Exception: java.lang.IllegalStateException: AES/CBC/NoPadding is not available
8df26d7: 2013-09-06 Mikhail Golubev - Merge remote-tracking branch 'origin/master'
87b1100: 2013-09-06 nik - xdebugger api: support grouping values in debugger trees
c1e214a: 2013-09-06 Vladislav.Soroka - IDEA-50450 Gradle code insight
f63250d: 2013-09-04 Alex Ruiz - Disabled "Use embedded Gradle" option for importing project.
517c614: 2013-09-06 Konstantin Bulenkov - remove refs to Project asap
636ac6d: 2013-09-06 Konstantin Bulenkov - IDEA-99897 When "block caret" mode is on, after deleting a character at the end of a line, the character deleted appears in inverse
021d4a5: 2013-06-12 Max Medvedev - Groovy formatter: blank lines in declarations
706feca: 2013-06-12 Max Medvedev - IDEA-113124 Groovy files in the navigation bar
81ba9a5: 2013-09-05 Vladimir Krivosheev - cleanup
198c147: 2013-06-12 Max Medvedev - IDEA-107520 Groovy Shell: support commands in groovy shell
cd1aa72: 2013-06-12 Max Medvedev - IDEA-69673 Generate toString() template Groovy GString style should be added
5e1454a: 2013-06-12 Max Medvedev - generateToString: shorten class references not only for java files
2509702: 2013-06-12 Max Medvedev - don't manually replace toString() if it exists; generate the new one in the appropriate place instead
2e72f08: 2013-06-09 Max Medvedev - Groovy: smart complete type definition body
c8ab923: 2013-06-09 Max Medvedev - Groovy: In-place introduce parameter: delegate
98ae7ed: 2013-09-04 Bas Leijdekkers - Fix all known "Field may be final" inspection problems 2 (IDEA-75321, IDEA-80439, IDEA-84561, IDEA-84614, IDEA-87373,IDEA-89711, IDEA-91969, IDEA-111396)
24184340: 2013-09-05 peter - update FixAllQuickfixTest test data, so that it identifies the quick fix unambiguously
082a0f9: 2013-09-05 Konstantin Bulenkov - make search everywhere available in current context
4eaae16: 2013-09-05 Konstantin Bulenkov - remove dead code
dde304f: 2013-09-05 Konstantin Bulenkov - refactor to make autoSelectOnMouseMove available in ListUtil
150d337: 2013-09-05 Dmitry Trofimov - Merge remote-tracking branch 'origin/master'
1790f99: 2013-09-05 Dmitry Trofimov - Merge remote-tracking branch 'origin/master'
981c3f6: 2013-09-05 Sergey Evdokimov - Rename class
06eb88d: 2013-09-05 Sergey Evdokimov - Add test for inserting maven dependency by smart completion
dc54349: 2013-09-05 Konstantin Kolosovsky - Merge branch 'svn1_8_new'
a742e91: 2013-09-05 Dmitry Trofimov - Take correct setting for console background color (PY-10737).
c55ba74: 2013-09-05 Nadya Zabrodina - ShellCommandLine changed to GeneralCommandline to provide shell variables to ide
bb3ff5f: 2013-09-05 Sergey Evdokimov - IDEA-112939 Smart dependency completion for pom.xml
d1daa65: 2013-09-05 Anna Kozlova - fix ranges
5ac8d00: 2013-09-05 Anna Kozlova - accept narrowing conversion from byte[] to T< extends Serializable> (IDEA-113225)
5e7db4f: 2013-09-05 Konstantin Kolosovsky - IDEA-112060 Notification added when working copy format and client version do not correspond to each other
804db7e: 2013-09-05 Konstantin Kolosovsky - IDEA-112060 Force validate executable if project is svn 1.8 working copy
cdc6f6b: 2013-09-05 Konstantin Kolosovsky - IDEA-112071 Refresh svn working copies/statuses if "use command line" option or path to executable changed
613144f: 2013-09-05 Konstantin Kolosovsky - Make equal SvnConfigurable and SvnVcs display names (to "show settings" work correctly)
002eadb: 2013-09-05 Serega Vasiliev - javaee libs,project structure, etc.
559ab96: 2013-09-05 peter - no matter if there are other variables having that constant value, it's still constant
bec4757: 2013-09-04 Mikhail Golubev - * Add error message when template variable used isn't defined * Template variables values are urlencoded during their substitution in URLs
c01b85b: 2013-09-04 Mikhail Golubev - Add sprint.ly integration
68d131b: 2013-09-05 peter - use actual (maybe unsaved) psi text for find usages (EA-49575)
b138d05: 2013-09-05 peter - rely less on mutable state in ChooseByNameBase.getNames (IDEA-112779)
f0dc4b1: 2013-09-05 Anna Kozlova - optimization: skip external usages processing when scope already contains everything
bfb94e0: 2013-09-05 Alexey Kudravtsev - renamed module editor-ui-impl to editor-ui-ex
d711697: 2013-09-05 peter - really focus existing project frame when opening already opened project (related to IDEA-113158)
57d5690: 2013-09-05 Anna Kozlova - logging for EA-49553 - assert: SingleInspectionProfilePanel.copyUsedSeveritiesIfUndefined
ed2cc9b: 2013-09-05 Anna Kozlova - logging for EA-49541 - assert: FileReference.rename
5a3cc7c: 2013-09-05 Roman Shevchenko - test framework: commit or dispose model
0735047: 2013-09-05 Anna Kozlova - scopes: escape dot as it is not a separator in file pattern (IDEA-113148)
6ae3bf7: 2013-09-05 Anna Kozlova - inference graph nodes: merge value/dependencies
f02d237: 2013-09-05 Konstantin Bulenkov - fix test data
830b9c1: 2013-09-05 Konstantin Bulenkov - better english
400062d: 2013-09-05 Sergey Evdokimov - Make GrailsRunConfiguration singleton by default.
8caf8af: 2013-09-05 Vladimir Krivosheev - add javadoc
32394f0: 2013-09-05 Vladimir Krivosheev - WEB-7511 "Evaluate Expression" window does not build correct path to currently selected object node
d59afd6: 2013-09-05 nik - xdebugger: removed duplicated 'Collecting data' text value node
32d3038: 2013-09-05 nik - unused class deleted
42255de: 2013-09-05 nik - xdebugger api streamlined: reworked the way node presentation is customized
36d908c: 2013-09-05 Sergey Evdokimov - IDEA-113188 Go to related files works incorrectly for Model and Controller in Groovy
55a5b28: 2013-09-05 Dmitry Avdeev - final methods in task api
cd0f640: 2013-09-04 Dmitry Avdeev - running tests without ModuleTypeManager
a41a8dc: 2013-09-05 Svetlana.Zemlyanskaya - Arrangement: make tokens aware of their type (author=Roman.Shein)
20bfe63: 2013-06-09 Max Medvedev - IDEA-71176 Encapsulate Java fields should update Groovy usages
30889b4: 2013-06-08 Max Medvedev - pluggable EncapsulateFields refactoring
a3ed6bd: 2013-06-08 Max Medvedev - refactor EncapsulateFieldProcessor
b7103d5: 2013-09-04 Max Medvedev - IDEA-113176 Groovy: place caret inside parentheses when compliting constructors
b44e415: 2013-09-04 Vladimir Krivosheev - NotNull, StreamProvider.listSubFiles accept roaming type
89f6078: 2013-09-04 Vladimir Krivosheev - init WEB-7511 "Evaluate Expression" window does not build correct path to currently selected object node Now only hint show correct evaluated expression
faaea11: 2013-09-04 Vladimir Krivosheev - remove deprecated method
98d4f5e: 2013-09-04 Vladimir Krivosheev - cleanup, remove deprecated method
f4a27e8: 2013-09-04 peter - CachedValueProvider.Result: force non-empty list of not-null dependencies
19df6f4: 2013-09-04 Dmitry Trofimov - Merge remote-tracking branch 'origin/master'
b12d474: 2013-09-04 Andrey Vlasovskikh - Merge branch 'python-fixes'
824377b: 2013-09-04 Andrey Vlasovskikh - Use new serializer for Python shadowing inspection
9bc2733: 2013-09-04 peter - single-pass control flow building
257d23a: 2013-09-04 peter - IDEA-112474 Expression might evaluate to null and not @Nullable annotated inspection is not aware of @Contract
e586777: 2013-09-04 peter - a more descriptive DupInstruction.toString
9c9e366: 2013-09-04 peter - dfa: pop all the contract-unchecked arguments from stack (IDEA-112500)
6c2ead1: 2013-09-04 jgindin - Branch view in RepositoryTab
616f50f: 2013-09-04 Konstantin Kolosovsky - Merge branch 'svn1_8_new'
631a6ae: 2013-09-04 Konstantin Bulenkov - IDEA-113217 Check spelling and grammar in Community Bundles
45009eb: 2013-09-04 Konstantin Bulenkov - IDEA-113216 Darcula: Equal sign is too bright in properties files
711b2f5: 2013-09-04 Konstantin Kolosovsky - IDEA-94942 Force separate SVNKit client for each info request (to prevent multithreaded issues)
9ea7a68: 2013-09-04 Konstantin Bulenkov - IDEA-113215 GSP looks weird under Darcula
76f2e32: 2013-09-04 Konstantin Kolosovsky - IDEA-94942 Removed unused JavaHL code
3a8a697: 2013-09-04 Vladimir Krivosheev - fix possible NPE
1dd1635: 2013-09-04 Vladimir Krivosheev - We must not use variable if it is not yet set — we must set channel in "init" handler, but not in "connected" handler. Issue is actual under windows (I don't know why).
4860142: 2013-09-04 Mikhail Golubev - Change TaskBuilder constructor: repository field is mandatory
ccb5502: 2013-09-04 Dmitry Trofimov - Merge remote-tracking branch 'origin/master'
d43513f: 2013-09-03 Dmitry Trofimov - Variable view in Python Console.
dd251c7: 2013-09-03 Dmitry Trofimov - Merge remote-tracking branch 'origin/master'
dc83844: 2013-09-03 Dmitry Trofimov - Prevent CCE.
Change-Id: I9ce8f336e5ab08b9a26d806a3faa8db7e0d9813f
Diffstat (limited to 'java/java-impl/src')
20 files changed, 804 insertions, 545 deletions
diff --git a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java index c3f9778677cc..fda11fd67b11 100644 --- a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java @@ -395,12 +395,11 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM continue; } final String externalName = getExternalName(listOwner, false); - final String oldExternalName = getNormalizedExternalName(listOwner); final List<XmlTag> tagsToProcess = new ArrayList<XmlTag>(); for (XmlTag tag : rootTag.getSubTags()) { String className = StringUtil.unescapeXml(tag.getAttributeValue("name")); - if (!Comparing.strEqual(className, externalName) && !Comparing.strEqual(className, oldExternalName)) { + if (!Comparing.strEqual(className, externalName)) { continue; } for (XmlTag annotationTag : tag.getSubTags()) { diff --git a/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java b/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java index 8e9b0b2ae484..f1ce89e76de1 100644 --- a/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java @@ -307,7 +307,7 @@ public class TargetElementUtil extends TargetElementUtilBase { if (referenceExpression != null && element instanceof PsiMethod) { final PsiClass[] memberClass = getMemberClass(referenceExpression, element); if (memberClass != null && memberClass.length == 1) { - return CachedValuesManager.getManager(element.getProject()).getCachedValue(referenceExpression, new CachedValueProvider<SearchScope>() { + return CachedValuesManager.getCachedValue(referenceExpression, new CachedValueProvider<SearchScope>() { @Nullable @Override public Result<SearchScope> compute() { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java index 26b9fdb52086..151619aac383 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -35,6 +35,7 @@ import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.text.StringUtil; import com.intellij.patterns.ElementPattern; import com.intellij.patterns.PatternCondition; +import com.intellij.patterns.PsiJavaElementPattern; import com.intellij.patterns.PsiNameValuePairPattern; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; @@ -78,6 +79,8 @@ public class JavaCompletionContributor extends CompletionContributor { public static final ElementPattern<PsiElement> ANNOTATION_NAME = psiElement(). withParents(PsiJavaCodeReferenceElement.class, PsiAnnotation.class).afterLeaf("@"); + private static final PsiJavaElementPattern.Capture<PsiElement> UNEXPECTED_REFERENCE_AFTER_DOT = + psiElement().afterLeaf(".").insideStarting(psiExpressionStatement()); private static JavaCompletionData getCompletionData(LanguageLevel level) { final Set<Map.Entry<LanguageLevel, JavaCompletionData>> entries = ourCompletionData.entrySet(); @@ -203,7 +206,7 @@ public class JavaCompletionContributor extends CompletionContributor { return; } - if (AFTER_NUMBER_LITERAL.accepts(position)) { + if (AFTER_NUMBER_LITERAL.accepts(position) || UNEXPECTED_REFERENCE_AFTER_DOT.accepts(position)) { _result.stopHere(); return; } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java index d995a9e3d475..fc0baa591c30 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight.completion; +import com.intellij.codeInsight.TailType; import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler; import com.intellij.codeInsight.lookup.*; import com.intellij.codeInsight.template.impl.TemplateManagerImpl; @@ -121,10 +122,10 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor { addLookupItems(set, suggestedNameInfo, matcher, project, suggestedNames); if (!hasStartMatches(set, matcher)) { if (type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) && matcher.prefixMatches("object")) { - set.add(LookupElementBuilder.create("object")); + set.add(withInsertHandler(suggestedNameInfo, LookupElementBuilder.create("object"))); } if (type.equalsToText(CommonClassNames.JAVA_LANG_STRING) && matcher.prefixMatches("string")) { - set.add(LookupElementBuilder.create("string")); + set.add(withInsertHandler(suggestedNameInfo, LookupElementBuilder.create("string"))); } } @@ -422,14 +423,23 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor { LookupElement element = PrioritizedLookupElement.withPriority(LookupElementBuilder.create(name).withAutoCompletionPolicy(AutoCompletionPolicy.GIVE_CHANCE_TO_OVERWRITE), -i); if (callback != null) { - element = LookupElementDecorator.withInsertHandler(element, new InsertHandler<LookupElementDecorator<LookupElement>>() { - @Override - public void handleInsert(InsertionContext context, LookupElementDecorator<LookupElement> item) { - callback.nameChosen(item.getLookupString()); - } - }); + element = withInsertHandler(callback, element); } lookupElements.add(element); } } + + private static LookupElementDecorator<LookupElement> withInsertHandler(final SuggestedNameInfo callback, LookupElement element) { + return LookupElementDecorator.withInsertHandler(element, new InsertHandler<LookupElementDecorator<LookupElement>>() { + @Override + public void handleInsert(InsertionContext context, LookupElementDecorator<LookupElement> item) { + TailType tailType = LookupItem.getDefaultTailType(context.getCompletionChar()); + if (tailType != null) { + context.setAddCompletionChar(false); + tailType.processTail(context.getEditor(), context.getTailOffset()); + } + callback.nameChosen(item.getLookupString()); + } + }); + } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/SameSignatureCallParametersProvider.java b/java/java-impl/src/com/intellij/codeInsight/completion/SameSignatureCallParametersProvider.java index 0cd697b6eb31..d3f0b2e62782 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/SameSignatureCallParametersProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/SameSignatureCallParametersProvider.java @@ -34,9 +34,8 @@ import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; import java.util.Map; +import java.util.Set; import static com.intellij.patterns.PlatformPatterns.psiElement; @@ -55,7 +54,7 @@ class SameSignatureCallParametersProvider extends CompletionProvider<CompletionP @NotNull CompletionResultSet result) { final PsiCall methodCall = PsiTreeUtil.getParentOfType(parameters.getPosition(), PsiCall.class); assert methodCall != null; - List<Pair<PsiMethod, PsiSubstitutor>> candidates = getCallCandidates(methodCall); + Set<Pair<PsiMethod, PsiSubstitutor>> candidates = getCallCandidates(methodCall); PsiMethod container = PsiTreeUtil.getParentOfType(methodCall, PsiMethod.class); while (container != null) { @@ -93,8 +92,8 @@ class SameSignatureCallParametersProvider extends CompletionProvider<CompletionP return TailTypeDecorator.withTail(element, ExpectedTypesProvider.getFinalCallParameterTailType(call, invoked.getReturnType(), invoked)); } - private static List<Pair<PsiMethod, PsiSubstitutor>> getCallCandidates(PsiCall expression) { - List<Pair<PsiMethod, PsiSubstitutor>> candidates = new ArrayList<Pair<PsiMethod, PsiSubstitutor>>(); + private static Set<Pair<PsiMethod, PsiSubstitutor>> getCallCandidates(PsiCall expression) { + Set<Pair<PsiMethod, PsiSubstitutor>> candidates = ContainerUtil.newLinkedHashSet(); JavaResolveResult[] results; if (expression instanceof PsiMethodCallExpression) { results = ((PsiMethodCallExpression)expression).getMethodExpression().multiResolve(false); @@ -108,7 +107,7 @@ class SameSignatureCallParametersProvider extends CompletionProvider<CompletionP final PsiClass psiClass = ((PsiMethod)element).getContainingClass(); if (psiClass != null) { for (Pair<PsiMethod, PsiSubstitutor> overload : psiClass.findMethodsAndTheirSubstitutorsByName(((PsiMethod)element).getName(), true)) { - candidates.add(overload); + candidates.add(Pair.create(overload.first, candidate.getSubstitutor().putAll(overload.second))); } break; } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java index 97629fbaff71..446a1f1662af 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java @@ -407,11 +407,11 @@ public class PostHighlightingPass extends TextEditorHighlightingPass { @NotNull PsiIdentifier identifier, @NotNull ProgressIndicator progress, @NotNull GlobalUsageHelper helper) { + if (HighlightUtil.isSerializationImplicitlyUsedField(field)) { + return null; + } if (field.hasModifierProperty(PsiModifier.PRIVATE)) { if (!myRefCountHolder.isReferenced(field) && !isImplicitUsage(field, progress)) { - if (HighlightUtil.isSerializationImplicitlyUsedField(field)) { - return null; - } String message = JavaErrorMessages.message("private.field.is.not.used", identifier.getText()); HighlightInfo highlightInfo = suggestionsToMakeFieldUsed(field, identifier, message); diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java index 228d3f712934..4d53c2c97f9d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java @@ -69,6 +69,7 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor { fixers.add(new MissingForeachBodyFixer()); fixers.add(new ParameterListFixer()); fixers.add(new MissingMethodBodyFixer()); + fixers.add(new MissingClassBodyFixer()); fixers.add(new MissingReturnExpressionFixer()); fixers.add(new MissingThrowExpressionFixer()); fixers.add(new ParenthesizedFixer()); diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingClassBodyFixer.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingClassBodyFixer.java new file mode 100644 index 000000000000..1a5876191cb6 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingClassBodyFixer.java @@ -0,0 +1,21 @@ +package com.intellij.codeInsight.editorActions.smartEnter; + +import com.intellij.openapi.editor.Editor; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.util.IncorrectOperationException; + +/** + * @author peter + */ +public class MissingClassBodyFixer implements Fixer { + @Override + public void apply(Editor editor, JavaSmartEnterProcessor processor, PsiElement psiElement) throws IncorrectOperationException { + if (!(psiElement instanceof PsiClass)) return; + PsiClass psiClass = (PsiClass) psiElement; + + if (psiClass.getLBrace() == null) { + editor.getDocument().insertString(psiClass.getTextRange().getEndOffset(), " {\n}"); + } + } +} diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/ui/GenerateEqualsWizard.java b/java/java-impl/src/com/intellij/codeInsight/generation/ui/GenerateEqualsWizard.java index d76caeda89c4..85e9674fc2bb 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/ui/GenerateEqualsWizard.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/ui/GenerateEqualsWizard.java @@ -32,7 +32,6 @@ import com.intellij.refactoring.util.classMembers.MemberInfo; import com.intellij.ui.NonFocusableCheckBox; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.event.ActionEvent; @@ -341,11 +340,5 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass, public JComponent getComponent() { return myPanel; } - - @Override - @Nullable - public Icon getIcon() { - return null; - } } } diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java new file mode 100644 index 000000000000..2f856b99f5ea --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java @@ -0,0 +1,123 @@ +/* + * 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.codeInsight.AnnotationUtil; +import com.intellij.codeInsight.ExternalAnnotationsManager; +import com.intellij.codeInsight.intention.AddAnnotationPsiFix; +import com.intellij.codeInsight.intention.impl.BaseIntentionAction; +import com.intellij.openapi.application.AccessToken; +import com.intellij.openapi.application.WriteAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.InputValidatorEx; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.generate.tostring.util.StringUtil; + +/** + * @author peter + */ +public class EditContractIntention extends BaseIntentionAction { + + @NotNull + @Override + public String getFamilyName() { + return "Edit method contract"; + } + + @Nullable + private static PsiMethod getTargetMethod(@NotNull Project project, Editor editor, PsiFile file) { + PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); + if (element == null) return null; + if (!PsiUtil.isLanguageLevel5OrHigher(element)) return null; + if (!element.getManager().isInProject(element) || CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS) { + final PsiModifierListOwner owner = AddAnnotationPsiFix.getContainer(element); + if (owner instanceof PsiMethod) { + return (PsiMethod)owner; + } + } + return null; + } + + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + final PsiMethod method = getTargetMethod(project, editor, file); + if (method != null) { + boolean hasContract = ControlFlowAnalyzer.findContractAnnotation(method) != null; + setText(hasContract ? "Edit method contract" : "Add method contract"); + return true; + } + return false; + } + + @Override + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + final PsiMethod method = getTargetMethod(project, editor, file); + assert method != null; + PsiAnnotation existingAnno = ControlFlowAnalyzer.findContractAnnotation(method); + String oldContract = existingAnno != null ? AnnotationUtil.getStringAttributeValue(existingAnno, null) : null; + String prompt = + "<html>Please specify the contract text<p>" + + "Example: <code>_, null -> false</code><br>" + + "<small>See intention action description for more details</small></html>"; + String newContract = Messages.showInputDialog(project, prompt, "Edit Method Contract", null, oldContract, new InputValidatorEx() { + @Nullable + @Override + public String getErrorText(String inputString) { + if (StringUtil.isEmpty(inputString)) return null; + + return DataFlowInspectionBase.checkContract(method, inputString); + } + + @Override + public boolean checkInput(String inputString) { + return getErrorText(inputString) == null; + } + + @Override + public boolean canClose(String inputString) { + return checkInput(inputString); + } + }); + if (newContract == null) return; + + AccessToken token = WriteAction.start(); + try { + ExternalAnnotationsManager manager = ExternalAnnotationsManager.getInstance(project); + manager.deannotate(method, ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT); + if (StringUtil.isNotEmpty(newContract)) { + PsiAnnotation mockAnno = JavaPsiFacade.getElementFactory(project).createAnnotationFromText("@Foo(\"" + newContract + "\")", null); + manager.annotateExternally(method, ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT, file, + mockAnno.getParameterList().getAttributes()); + } + } + finally { + token.finish(); + } + } + + @Override + public boolean startInWriteAction() { + return false; + } +} diff --git a/java/java-impl/src/com/intellij/openapi/roots/LibraryDependencyScopeSuggester.java b/java/java-impl/src/com/intellij/openapi/roots/LibraryDependencyScopeSuggester.java index 1cc0795255d9..66075d9332c3 100644 --- a/java/java-impl/src/com/intellij/openapi/roots/LibraryDependencyScopeSuggester.java +++ b/java/java-impl/src/com/intellij/openapi/roots/LibraryDependencyScopeSuggester.java @@ -28,4 +28,15 @@ public abstract class LibraryDependencyScopeSuggester { @Nullable public abstract DependencyScope getDefaultDependencyScope(@NotNull Library library); + + @NotNull + public static DependencyScope getDefaultScope(@NotNull Library library) { + for (LibraryDependencyScopeSuggester suggester : EP_NAME.getExtensions()) { + DependencyScope scope = suggester.getDefaultDependencyScope(library); + if (scope != null) { + return scope; + } + } + return DependencyScope.COMPILE; + } } diff --git a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDescriptor.java b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDescriptor.java deleted file mode 100644 index 8f1162e34bc0..000000000000 --- a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDescriptor.java +++ /dev/null @@ -1,54 +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. - */ - -/* - * User: anna - * Date: 23-Oct-2009 - */ -package com.intellij.refactoring.encapsulateFields; - -import com.intellij.psi.PsiField; -import com.intellij.psi.PsiMethod; -import com.intellij.psi.PsiModifier; -import org.jetbrains.annotations.Nullable; - -public interface EncapsulateFieldsDescriptor { - PsiField[] getSelectedFields(); - - String[] getGetterNames(); - - String[] getSetterNames(); - - @Nullable - PsiMethod[] getGetterPrototypes(); - - @Nullable - PsiMethod[] getSetterPrototypes(); - - boolean isToEncapsulateGet(); - - boolean isToEncapsulateSet(); - - boolean isToUseAccessorsWhenAccessible(); - - @PsiModifier.ModifierConstant - String getFieldsVisibility(); - - @PsiModifier.ModifierConstant - String getAccessorsVisibility(); - - int getJavadocPolicy(); -} 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 e8d41e0efa8c..8c4f926900f5 100644 --- a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.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,15 +15,14 @@ */ package com.intellij.refactoring.encapsulateFields; -import com.intellij.codeInsight.generation.GenerateMembersUtil; import com.intellij.icons.AllIcons; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Iconable; import com.intellij.psi.*; -import com.intellij.psi.util.PropertyUtil; import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.PsiFormatUtilBase; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.JavaRefactoringSettings; import com.intellij.refactoring.RefactoringBundle; @@ -32,10 +31,9 @@ import com.intellij.refactoring.ui.RefactoringDialog; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.RefactoringMessageUtil; import com.intellij.ui.*; +import com.intellij.ui.table.JBTable; import com.intellij.util.IconUtil; -import com.intellij.util.IncorrectOperationException; import com.intellij.util.ui.EmptyIcon; -import com.intellij.util.ui.Table; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; @@ -50,15 +48,17 @@ import java.awt.event.*; import java.util.Set; public class EncapsulateFieldsDialog extends RefactoringDialog implements EncapsulateFieldsDescriptor { - private static final Logger LOG = Logger.getInstance( - "#com.intellij.refactoring.encapsulateFields.EncapsulateFieldsDialog" - ); + private static final Logger LOG = Logger.getInstance(EncapsulateFieldsDialog.class); + + private static final String REFACTORING_NAME = RefactoringBundle.message("encapsulate.fields.title"); private static final int CHECKED_COLUMN = 0; private static final int FIELD_COLUMN = 1; private static final int GETTER_COLUMN = 2; private static final int SETTER_COLUMN = 3; + private final EncapsulateFieldHelper myHelper; + private final Project myProject; private final PsiClass myClass; @@ -85,7 +85,6 @@ public class EncapsulateFieldsDialog extends RefactoringDialog implements Encaps private final JRadioButton myRbAccessorProtected = new JRadioButton(); private final JRadioButton myRbAccessorPrivate = new JRadioButton(); private final JRadioButton myRbAccessorPackageLocal = new JRadioButton(); - private static final String REFACTORING_NAME = RefactoringBundle.message("encapsulate.fields.title"); private DocCommentPanel myJavadocPolicy; { @@ -100,10 +99,11 @@ public class EncapsulateFieldsDialog extends RefactoringDialog implements Encaps myRbFieldProtected.setFocusable(false); } - public EncapsulateFieldsDialog(Project project, PsiClass aClass, final Set preselectedFields) { + public EncapsulateFieldsDialog(Project project, PsiClass aClass, final Set preselectedFields, EncapsulateFieldHelper helper) { super(project, true); myProject = project; myClass = aClass; + myHelper = helper; String title = REFACTORING_NAME; String qName = myClass.getQualifiedName(); @@ -112,7 +112,7 @@ public class EncapsulateFieldsDialog extends RefactoringDialog implements Encaps } setTitle(title); - myFields = myClass.getFields(); + myFields = myHelper.getApplicableFields(myClass); myFieldNames = new String[myFields.length]; myCheckedMarks = new boolean[myFields.length]; myFinalMarks = new boolean[myFields.length]; @@ -126,69 +126,36 @@ public class EncapsulateFieldsDialog extends RefactoringDialog implements Encaps myFinalMarks[idx] = field.hasModifierProperty(PsiModifier.FINAL); myFieldNames[idx] = PsiFormatUtil.formatVariable(field, - PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER, + PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_TYPE | PsiFormatUtilBase.TYPE_AFTER, PsiSubstitutor.EMPTY ); - myGetterNames[idx] = PropertyUtil.suggestGetterName(myProject, field); - mySetterNames[idx] = PropertyUtil.suggestSetterName(myProject, field); - myGetterPrototypes[idx] = generateMethodPrototype(field, myGetterNames[idx], true); - mySetterPrototypes[idx] = generateMethodPrototype(field, mySetterNames[idx], false); + myGetterNames[idx] = myHelper.suggestGetterName(field); + mySetterNames[idx] = myHelper.suggestSetterName(field); + myGetterPrototypes[idx] = myHelper.generateMethodPrototype(field, myGetterNames[idx], true); + mySetterPrototypes[idx] = myHelper.generateMethodPrototype(field, mySetterNames[idx], false); } init(); } - public PsiField[] getSelectedFields() { - int[] rows = getCheckedRows(); - PsiField[] selectedFields = new PsiField[rows.length]; - for (int idx = 0; idx < rows.length; idx++) { - selectedFields[idx] = myFields[rows[idx]]; - } - return selectedFields; - } - - public String[] getGetterNames() { + public FieldDescriptor[] getSelectedFields() { int[] rows = getCheckedRows(); - String[] selectedGetters = new String[rows.length]; - for (int idx = 0; idx < rows.length; idx++) { - selectedGetters[idx] = myGetterNames[rows[idx]]; - } - return selectedGetters; - } + FieldDescriptor[] descriptors = new FieldDescriptor[rows.length]; - public String[] getSetterNames() { - int[] rows = getCheckedRows(); - String[] selectedSetters = new String[rows.length]; for (int idx = 0; idx < rows.length; idx++) { - selectedSetters[idx] = mySetterNames[rows[idx]]; - } - return selectedSetters; - } - - public PsiMethod[] getGetterPrototypes() { - if (isToEncapsulateGet()) { - int[] rows = getCheckedRows(); - PsiMethod[] selectedGetters = new PsiMethod[rows.length]; - for (int idx = 0; idx < rows.length; idx++) { - selectedGetters[idx] = myGetterPrototypes[rows[idx]]; - } - return selectedGetters; - } else { - return null; - } - } - - public PsiMethod[] getSetterPrototypes() { - if (isToEncapsulateSet()) { - int[] rows = getCheckedRows(); - PsiMethod[] selectedSetters = new PsiMethod[rows.length]; - for (int idx = 0; idx < rows.length; idx++) { - selectedSetters[idx] = mySetterPrototypes[rows[idx]]; - } - return selectedSetters; - } else { - return null; + descriptors[idx] = new FieldDescriptorImpl( + myFields[rows[idx]], + myGetterNames[rows[idx]], + mySetterNames[rows[idx]], + isToEncapsulateGet() + ? myGetterPrototypes[rows[idx]] + : null, + isToEncapsulateSet() + ? mySetterPrototypes[rows[idx]] + : null + ); } + return descriptors; } public boolean isToEncapsulateGet() { @@ -227,12 +194,17 @@ public class EncapsulateFieldsDialog extends RefactoringDialog implements Encaps return myJavadocPolicy.getPolicy(); } + @Override + public PsiClass getTargetClass() { + return myClass; + } + protected String getDimensionServiceKey() { return "#com.intellij.refactoring.encapsulateFields.EncalpsulateFieldsDialog"; } @PsiModifier.ModifierConstant -public String getAccessorsVisibility() { + public String getAccessorsVisibility() { if (myRbAccessorPublic.isSelected()) { return PsiModifier.PUBLIC; } else if (myRbAccessorProtected.isSelected()) { @@ -376,7 +348,7 @@ public String getAccessorsVisibility() { private JComponent createTable() { myTableModel = new MyTableModel(); - myTable = new Table(myTableModel); + myTable = new JBTable(myTableModel); myTable.setSurrendersFocusOnKeystroke(true); MyTableRenderer renderer = new MyTableRenderer(); TableColumnModel columnModel = myTable.getColumnModel(); @@ -508,21 +480,6 @@ public String getAccessorsVisibility() { return getCheckedRows().length > 0; } - private PsiMethod generateMethodPrototype(PsiField field, String methodName, boolean isGetter) { - PsiMethod prototype = isGetter - ? GenerateMembersUtil.generateGetterPrototype(field) - : GenerateMembersUtil.generateSetterPrototype(field); - try { - PsiElementFactory factory = JavaPsiFacade.getInstance(field.getProject()).getElementFactory(); - PsiIdentifier identifier = factory.createIdentifier(methodName); - prototype.getNameIdentifier().replace(identifier); - //prototype.getModifierList().setModifierProperty(getAccessorsVisibility(), true); - return prototype; - } catch (IncorrectOperationException e) { - return null; - } - } - private int[] getCheckedRows() { int count = 0; for (boolean checkedMark : myCheckedMarks) { @@ -611,12 +568,12 @@ public String getAccessorsVisibility() { switch (columnIndex) { case GETTER_COLUMN: myGetterNames[rowIndex] = name; - myGetterPrototypes[rowIndex] = generateMethodPrototype(field, name, true); + myGetterPrototypes[rowIndex] = myHelper.generateMethodPrototype(field, name, true); break; case SETTER_COLUMN: mySetterNames[rowIndex] = name; - mySetterPrototypes[rowIndex] = generateMethodPrototype(field, name, false); + mySetterPrototypes[rowIndex] = myHelper.generateMethodPrototype(field, name, false); break; default: @@ -639,8 +596,8 @@ public String getAccessorsVisibility() { case FIELD_COLUMN: { Icon icon = field.getIcon(Iconable.ICON_FLAG_VISIBILITY); - MyTableRenderer.this.setIcon(icon); - MyTableRenderer.this.setDisabledIcon(icon); + setIcon(icon); + setDisabledIcon(icon); configureColors(isSelected, table, hasFocus, row, column); break; } @@ -670,21 +627,21 @@ public String getAccessorsVisibility() { } } } else { - MyTableRenderer.this.setForeground(JBColor.RED); + setForeground(JBColor.RED); } RowIcon icon = new RowIcon(2); icon.setIcon(methodIcon, 0); icon.setIcon(overrideIcon, 1); - MyTableRenderer.this.setIcon(icon); - MyTableRenderer.this.setDisabledIcon(icon); + setIcon(icon); + setDisabledIcon(icon); break; } default: { - MyTableRenderer.this.setIcon(null); - MyTableRenderer.this.setDisabledIcon(null); + setIcon(null); + setDisabledIcon(null); } } boolean enabled = myCheckedMarks[row]; diff --git a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsHandler.java b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsHandler.java index 925c63147d85..8e618ed988bb 100644 --- a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsHandler.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. @@ -96,7 +96,8 @@ public class EncapsulateFieldsHandler implements RefactoringActionHandler { preselectedFields.add(field); } else { - String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("fields.to.be.refactored.should.belong.to.the.same.class")); + String message = RefactoringBundle.getCannotRefactorMessage( + RefactoringBundle.message("fields.to.be.refactored.should.belong.to.the.same.class")); Editor editor = PlatformDataKeys.EDITOR.getData(dataContext); CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.ENCAPSULATE_FIELDS); return; @@ -108,12 +109,14 @@ public class EncapsulateFieldsHandler implements RefactoringActionHandler { LOG.assertTrue(aClass != null); final PsiField[] fields = aClass.getFields(); if (fields.length == 0) { - CommonRefactoringUtil.showErrorHint(project, PlatformDataKeys.EDITOR.getData(dataContext), "Class has no fields to encapsulate", REFACTORING_NAME, HelpID.ENCAPSULATE_FIELDS); + CommonRefactoringUtil.showErrorHint(project, PlatformDataKeys.EDITOR.getData(dataContext), "Class has no fields to encapsulate", + REFACTORING_NAME, HelpID.ENCAPSULATE_FIELDS); return; } if (aClass.isInterface()) { - String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("encapsulate.fields.refactoring.cannot.be.applied.to.interface")); + String message = RefactoringBundle.getCannotRefactorMessage( + RefactoringBundle.message("encapsulate.fields.refactoring.cannot.be.applied.to.interface")); Editor editor = PlatformDataKeys.EDITOR.getData(dataContext); CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.ENCAPSULATE_FIELDS); return; @@ -121,10 +124,15 @@ public class EncapsulateFieldsHandler implements RefactoringActionHandler { if (!CommonRefactoringUtil.checkReadOnlyStatus(project, aClass)) return; - EncapsulateFieldsDialog dialog = new EncapsulateFieldsDialog( - project, - aClass, - preselectedFields); + EncapsulateFieldsDialog dialog = createDialog(project, aClass, preselectedFields); dialog.show(); } + + protected EncapsulateFieldsDialog createDialog(Project project, PsiClass aClass, HashSet<PsiField> preselectedFields) { + return new EncapsulateFieldsDialog( + project, + aClass, + preselectedFields, + new JavaEncapsulateFieldHelper()); + } }
\ No newline at end of file diff --git a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java index fc87374b6ad3..986f98b5fc39 100644 --- a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java @@ -1,6 +1,6 @@ /* - * 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,17 +20,11 @@ import com.intellij.lang.findUsages.DescriptiveNameUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; -import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.search.searches.ClassInheritorsSearch; import com.intellij.psi.search.searches.ReferencesSearch; -import com.intellij.psi.tree.IElementType; -import com.intellij.psi.util.InheritanceUtil; -import com.intellij.psi.util.PsiFormatUtil; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.*; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.util.CommonRefactoringUtil; @@ -41,12 +35,10 @@ import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageViewDescriptor; import com.intellij.usageView.UsageViewUtil; import com.intellij.util.IncorrectOperationException; -import com.intellij.util.VisibilityUtil; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.containers.MultiMap; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.*; @@ -56,7 +48,7 @@ public class EncapsulateFieldsProcessor extends BaseRefactoringProcessor { private PsiClass myClass; @NotNull private final EncapsulateFieldsDescriptor myDescriptor; - private final PsiField[] myFields; + private final FieldDescriptor[] myFieldDescriptors; private HashMap<String,PsiMethod> myNameToGetter; private HashMap<String,PsiMethod> myNameToSetter; @@ -64,14 +56,26 @@ public class EncapsulateFieldsProcessor extends BaseRefactoringProcessor { public EncapsulateFieldsProcessor(Project project, @NotNull EncapsulateFieldsDescriptor descriptor) { super(project); myDescriptor = descriptor; - myFields = myDescriptor.getSelectedFields(); - myClass = myFields[0].getContainingClass(); + myFieldDescriptors = descriptor.getSelectedFields(); + myClass = descriptor.getTargetClass(); + } + + public static void setNewFieldVisibility(PsiField field, EncapsulateFieldsDescriptor descriptor) { + try { + if (descriptor.getFieldsVisibility() != null) { + field.normalizeDeclaration(); + PsiUtil.setModifierProperty(field, descriptor.getFieldsVisibility(), true); + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } } @NotNull protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { - PsiField[] fields = new PsiField[myFields.length]; - System.arraycopy(myFields, 0, fields, 0, myFields.length); + FieldDescriptor[] fields = new FieldDescriptor[myFieldDescriptors.length]; + System.arraycopy(myFieldDescriptors, 0, fields, 0, myFieldDescriptors.length); return new EncapsulateFieldsViewDescriptor(fields); } @@ -82,28 +86,27 @@ public class EncapsulateFieldsProcessor extends BaseRefactoringProcessor { protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) { final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>(); - final PsiMethod[] getterPrototypes = myDescriptor.getGetterPrototypes(); - final PsiMethod[] setterPrototypes = myDescriptor.getSetterPrototypes(); - - checkExistingMethods(getterPrototypes, conflicts, true); - checkExistingMethods(setterPrototypes, conflicts, false); + checkExistingMethods(conflicts, true); + checkExistingMethods(conflicts, false); final Collection<PsiClass> classes = ClassInheritorsSearch.search(myClass).findAll(); - for (int i = 0; i < myFields.length; i++) { - final PsiField field = myFields[i]; + for (FieldDescriptor fieldDescriptor : myFieldDescriptors) { final Set<PsiMethod> setters = new HashSet<PsiMethod>(); final Set<PsiMethod> getters = new HashSet<PsiMethod>(); for (PsiClass aClass : classes) { - final PsiMethod getterOverrider = getterPrototypes != null ? aClass.findMethodBySignature(getterPrototypes[i], false) : null; + final PsiMethod getterOverrider = + myDescriptor.isToEncapsulateGet() ? aClass.findMethodBySignature(fieldDescriptor.getGetterPrototype(), false) : null; if (getterOverrider != null) { getters.add(getterOverrider); } - final PsiMethod setterOverrider = setterPrototypes != null ? aClass.findMethodBySignature(setterPrototypes[i], false) : null; + final PsiMethod setterOverrider = + myDescriptor.isToEncapsulateSet() ? aClass.findMethodBySignature(fieldDescriptor.getSetterPrototype(), false) : null; if (setterOverrider != null) { setters.add(setterOverrider); } } if (!getters.isEmpty() || !setters.isEmpty()) { + final PsiField field = fieldDescriptor.getField(); for (PsiReference reference : ReferencesSearch.search(field)) { final PsiElement place = reference.getElement(); LOG.assertTrue(place instanceof PsiReferenceExpression); @@ -132,9 +135,19 @@ public class EncapsulateFieldsProcessor extends BaseRefactoringProcessor { return showConflicts(conflicts, refUsages.get()); } - private void checkExistingMethods(PsiMethod[] prototypes, MultiMap<PsiElement, String> conflicts, boolean isGetter) { - if(prototypes == null) return; - for (PsiMethod prototype : prototypes) { + private void checkExistingMethods(MultiMap<PsiElement, String> conflicts, boolean isGetter) { + if (isGetter) { + if (!myDescriptor.isToEncapsulateGet()) return; + } + else { + if (!myDescriptor.isToEncapsulateSet()) return; + } + + for (FieldDescriptor descriptor : myFieldDescriptors) { + PsiMethod prototype = isGetter + ? descriptor.getGetterPrototype() + : descriptor.getSetterPrototype(); + final PsiType prototypeReturnType = prototype.getReturnType(); PsiMethod existing = myClass.findMethodBySignature(prototype, true); if (existing != null) { @@ -142,8 +155,8 @@ public class EncapsulateFieldsProcessor extends BaseRefactoringProcessor { if (!RefactoringUtil.equivalentTypes(prototypeReturnType, returnType, myClass.getManager())) { final String descr = PsiFormatUtil.formatMethod(existing, PsiSubstitutor.EMPTY, - PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS | PsiFormatUtil.SHOW_TYPE, - PsiFormatUtil.SHOW_TYPE + PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS | PsiFormatUtilBase.SHOW_TYPE, + PsiFormatUtilBase.SHOW_TYPE ); String message = isGetter ? RefactoringBundle.message("encapsulate.fields.getter.exists", CommonRefactoringUtil.htmlEmphasize(descr), @@ -181,144 +194,112 @@ public class EncapsulateFieldsProcessor extends BaseRefactoringProcessor { } @NotNull protected UsageInfo[] findUsages() { - boolean findGet = myDescriptor.isToEncapsulateGet(); - boolean findSet = myDescriptor.isToEncapsulateSet(); - PsiModifierList newModifierList = null; - final JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject); - if (!myDescriptor.isToUseAccessorsWhenAccessible()){ - PsiElementFactory factory = facade.getElementFactory(); - try{ - PsiField field = factory.createField("a", PsiType.INT); - setNewFieldVisibility(field); - newModifierList = field.getModifierList(); - } - catch(IncorrectOperationException e){ - LOG.error(e); - } - } - PsiMethod[] getterPrototypes = myDescriptor.getGetterPrototypes(); - PsiMethod[] setterPrototypes = myDescriptor.getSetterPrototypes(); - ArrayList<UsageInfo> array = new ArrayList<UsageInfo>(); - PsiField[] fields = myFields; - for(int i = 0; i < fields.length; i++){ - PsiField field = fields[i]; - for (final PsiReference reference : ReferencesSearch.search(field)) { - if (!(reference instanceof PsiReferenceExpression)) continue; - PsiReferenceExpression ref = (PsiReferenceExpression)reference; - // [Jeka] to avoid recursion in the field's accessors - if (findGet && isUsedInExistingAccessor(getterPrototypes[i], ref)) continue; - if (findSet && isUsedInExistingAccessor(setterPrototypes[i], ref)) continue; - if (!findGet) { - if (!PsiUtil.isAccessedForWriting(ref)) continue; + ArrayList<EncapsulateFieldUsageInfo> array = ContainerUtil.newArrayList(); + for (FieldDescriptor fieldDescriptor : myFieldDescriptors) { + for (final PsiReference reference : ReferencesSearch.search(fieldDescriptor.getField())) { + final PsiElement element = reference.getElement(); + if (element == null) continue; + + final EncapsulateFieldHelper helper = EncapsulateFieldHelper.getHelper(element.getLanguage()); + EncapsulateFieldUsageInfo usageInfo = helper.createUsage(myDescriptor, fieldDescriptor, reference); + if (usageInfo != null) { + array.add(usageInfo); } - if (!findSet || field.hasModifierProperty(PsiModifier.FINAL)) { - if (!PsiUtil.isAccessedForReading(ref)) continue; - } - if (!myDescriptor.isToUseAccessorsWhenAccessible()) { - PsiClass accessObjectClass = null; - PsiExpression qualifier = ref.getQualifierExpression(); - if (qualifier != null) { - accessObjectClass = (PsiClass)PsiUtil.getAccessObjectClass(qualifier).getElement(); - } - if (facade.getResolveHelper() - .isAccessible(field, newModifierList, ref, accessObjectClass, null)) { - continue; - } - } - UsageInfo usageInfo = new MyUsageInfo(ref, i); - array.add(usageInfo); } } - MyUsageInfo[] usageInfos = array.toArray(new MyUsageInfo[array.size()]); + EncapsulateFieldUsageInfo[] usageInfos = array.toArray(new EncapsulateFieldUsageInfo[array.size()]); return UsageViewUtil.removeDuplicatedUsages(usageInfos); } protected void refreshElements(PsiElement[] elements) { - LOG.assertTrue(elements.length == myFields.length); + LOG.assertTrue(elements.length == myFieldDescriptors.length); for (int idx = 0; idx < elements.length; idx++) { PsiElement element = elements[idx]; LOG.assertTrue(element instanceof PsiField); - myFields[idx] = (PsiField)element; + myFieldDescriptors[idx].refreshField((PsiField)element); } - myClass = myFields[0].getContainingClass(); + myClass = myFieldDescriptors[0].getField().getContainingClass(); } protected void performRefactoring(UsageInfo[] usages) { - // change visibility of fields - if (myDescriptor.getFieldsVisibility() != null){ - // "as is" - for (PsiField field : myFields) { - setNewFieldVisibility(field); - } + updateFieldVisibility(); + generateAccessors(); + processUsagesPerFile(usages); + } + + private void updateFieldVisibility() { + if (myDescriptor.getFieldsVisibility() == null) return; + + for (FieldDescriptor descriptor : myFieldDescriptors) { + setNewFieldVisibility(descriptor.getField(), myDescriptor); } + } + private void generateAccessors() { // generate accessors myNameToGetter = new HashMap<String, PsiMethod>(); myNameToSetter = new HashMap<String, PsiMethod>(); - for(int i = 0; i < myFields.length; i++){ + + for (FieldDescriptor fieldDescriptor : myFieldDescriptors) { final DocCommentPolicy<PsiDocComment> commentPolicy = new DocCommentPolicy<PsiDocComment>(myDescriptor.getJavadocPolicy()); - PsiField field = myFields[i]; + + PsiField field = fieldDescriptor.getField(); final PsiDocComment docComment = field.getDocComment(); - if (myDescriptor.isToEncapsulateGet()){ - PsiMethod[] prototypes = myDescriptor.getGetterPrototypes(); - assert prototypes != null; - final PsiMethod getter = addOrChangeAccessor(prototypes[i], myNameToGetter); + if (myDescriptor.isToEncapsulateGet()) { + final PsiMethod prototype = fieldDescriptor.getGetterPrototype(); + assert prototype != null; + final PsiMethod getter = addOrChangeAccessor(prototype, myNameToGetter); if (docComment != null) { final PsiDocComment getterJavadoc = (PsiDocComment)getter.addBefore(docComment, getter.getFirstChild()); commentPolicy.processNewJavaDoc(getterJavadoc); } } - if (myDescriptor.isToEncapsulateSet() && !field.hasModifierProperty(PsiModifier.FINAL)){ - PsiMethod[] prototypes = myDescriptor.getSetterPrototypes(); - assert prototypes != null; - addOrChangeAccessor(prototypes[i], myNameToSetter); + if (myDescriptor.isToEncapsulateSet() && !field.hasModifierProperty(PsiModifier.FINAL)) { + PsiMethod prototype = fieldDescriptor.getSetterPrototype(); + assert prototype != null; + addOrChangeAccessor(prototype, myNameToSetter); } if (docComment != null) { commentPolicy.processOldJavaDoc(docComment); } } + } - Map<PsiFile, List<MyUsageInfo>> usagesInFiles = new HashMap<PsiFile, List<MyUsageInfo>>(); + private void processUsagesPerFile(UsageInfo[] usages) { + Map<PsiFile, List<EncapsulateFieldUsageInfo>> usagesInFiles = new HashMap<PsiFile, List<EncapsulateFieldUsageInfo>>(); for (UsageInfo usage : usages) { PsiElement element = usage.getElement(); if (element == null) continue; final PsiFile file = element.getContainingFile(); - List<MyUsageInfo> usagesInFile = usagesInFiles.get(file); + List<EncapsulateFieldUsageInfo> usagesInFile = usagesInFiles.get(file); if (usagesInFile == null) { - usagesInFile = new ArrayList<MyUsageInfo>(); + usagesInFile = new ArrayList<EncapsulateFieldUsageInfo>(); usagesInFiles.put(file, usagesInFile); } - usagesInFile.add(((MyUsageInfo)usage)); + usagesInFile.add(((EncapsulateFieldUsageInfo)usage)); } - for (List<MyUsageInfo> usageInfos : usagesInFiles.values()) { + for (List<EncapsulateFieldUsageInfo> usageInfos : usagesInFiles.values()) { //this is to avoid elements to become invalid as a result of processUsage - final MyUsageInfo[] infos = usageInfos.toArray(new MyUsageInfo[usageInfos.size()]); + final EncapsulateFieldUsageInfo[] infos = usageInfos.toArray(new EncapsulateFieldUsageInfo[usageInfos.size()]); CommonRefactoringUtil.sortDepthFirstRightLeftOrder(infos); - for (MyUsageInfo info : infos) { - processUsage(info); + for (EncapsulateFieldUsageInfo info : infos) { + EncapsulateFieldHelper helper = EncapsulateFieldHelper.getHelper(info.getElement().getLanguage()); + helper.processUsage(info, + myDescriptor, + myNameToSetter.get(info.getFieldDescriptor().getSetterName()), + myNameToGetter.get(info.getFieldDescriptor().getGetterName()) + ); } } } - private void setNewFieldVisibility(PsiField field) { - try{ - if (myDescriptor.getFieldsVisibility() != null){ - field.normalizeDeclaration(); - PsiUtil.setModifierProperty(field, myDescriptor.getFieldsVisibility(), true); - } - } - catch(IncorrectOperationException e){ - LOG.error(e); - } - } - private PsiMethod addOrChangeAccessor(PsiMethod prototype, HashMap<String,PsiMethod> nameToAncestor) { PsiMethod existing = myClass.findMethodBySignature(prototype, false); PsiMethod result = existing; @@ -338,239 +319,4 @@ public class EncapsulateFieldsProcessor extends BaseRefactoringProcessor { } return null; } - - private boolean isUsedInExistingAccessor(PsiMethod prototype, PsiElement element) { - PsiMethod existingAccessor = myClass.findMethodBySignature(prototype, false); - if (existingAccessor != null) { - PsiElement parent = element; - while (parent != null) { - if (existingAccessor.equals(parent)) return true; - parent = parent.getParent(); - } - } - return false; - } - - private void processUsage(MyUsageInfo usage) { - PsiField field = myFields[usage.fieldIndex]; - boolean processGet = myDescriptor.isToEncapsulateGet(); - boolean processSet = myDescriptor.isToEncapsulateSet() && !field.hasModifierProperty(PsiModifier.FINAL); - if (!processGet && !processSet) return; - PsiElementFactory factory = JavaPsiFacade.getInstance(myProject).getElementFactory(); - - try{ - final PsiReferenceExpression expr = (PsiReferenceExpression)usage.getElement(); - if (expr == null) return; - final PsiElement parent = expr.getParent(); - if (parent instanceof PsiAssignmentExpression && expr.equals(((PsiAssignmentExpression)parent).getLExpression())){ - PsiAssignmentExpression assignment = (PsiAssignmentExpression)parent; - if (assignment.getRExpression() == null) return; - PsiJavaToken opSign = assignment.getOperationSign(); - IElementType opType = opSign.getTokenType(); - if (opType == JavaTokenType.EQ) { - { - if (!processSet) return; - final int fieldIndex = usage.fieldIndex; - final PsiExpression setterArgument = assignment.getRExpression(); - - PsiMethodCallExpression methodCall = createSetterCall(fieldIndex, setterArgument, expr); - - if (methodCall != null) { - assignment.replace(methodCall); - } - //TODO: check if value is used!!! - } - } - else if (opType == JavaTokenType.ASTERISKEQ || opType == JavaTokenType.DIVEQ || opType == JavaTokenType.PERCEQ || - opType == JavaTokenType.PLUSEQ || - opType == JavaTokenType.MINUSEQ || - opType == JavaTokenType.LTLTEQ || - opType == JavaTokenType.GTGTEQ || - opType == JavaTokenType.GTGTGTEQ || - opType == JavaTokenType.ANDEQ || - opType == JavaTokenType.OREQ || - opType == JavaTokenType.XOREQ) { - { - // Q: side effects of qualifier??! - - String opName = opSign.getText(); - LOG.assertTrue(StringUtil.endsWithChar(opName, '=')); - opName = opName.substring(0, opName.length() - 1); - - PsiExpression getExpr = expr; - if (processGet) { - final int fieldIndex = usage.fieldIndex; - final PsiMethodCallExpression getterCall = createGetterCall(fieldIndex, expr); - if (getterCall != null) { - getExpr = getterCall; - } - } - - @NonNls String text = "a" + opName + "b"; - PsiBinaryExpression binExpr = (PsiBinaryExpression)factory.createExpressionFromText(text, expr); - binExpr = (PsiBinaryExpression)CodeStyleManager.getInstance(myProject).reformat(binExpr); - binExpr.getLOperand().replace(getExpr); - binExpr.getROperand().replace(assignment.getRExpression()); - - PsiExpression setExpr; - if (processSet) { - setExpr = createSetterCall(usage.fieldIndex, binExpr, expr); - } - else { - text = "a = b"; - PsiAssignmentExpression assignment1 = (PsiAssignmentExpression)factory.createExpressionFromText(text, null); - assignment1 = (PsiAssignmentExpression)CodeStyleManager.getInstance(myProject).reformat(assignment1); - assignment1.getLExpression().replace(expr); - assignment1.getRExpression().replace(binExpr); - setExpr = assignment1; - } - - assignment.replace(setExpr); - //TODO: check if value is used!!! - } - } - } - else if (RefactoringUtil.isPlusPlusOrMinusMinus(parent)){ - IElementType sign; - if (parent instanceof PsiPrefixExpression){ - sign = ((PsiPrefixExpression)parent).getOperationTokenType(); - } - else{ - sign = ((PsiPostfixExpression)parent).getOperationTokenType(); - } - - PsiExpression getExpr = expr; - if (processGet){ - final int fieldIndex = usage.fieldIndex; - final PsiMethodCallExpression getterCall = createGetterCall(fieldIndex, expr); - if(getterCall != null) { - getExpr = getterCall; - } - } - - @NonNls String text; - if (sign == JavaTokenType.PLUSPLUS){ - text = "a+1"; - } - else{ - text = "a-1"; - } - PsiBinaryExpression binExpr = (PsiBinaryExpression)factory.createExpressionFromText(text, null); - binExpr = (PsiBinaryExpression)CodeStyleManager.getInstance(myProject).reformat(binExpr); - binExpr.getLOperand().replace(getExpr); - - PsiExpression setExpr; - if (processSet){ - final int fieldIndex = usage.fieldIndex; - setExpr = createSetterCall(fieldIndex, binExpr, expr); - } - else{ - text = "a = b"; - PsiAssignmentExpression assignment = (PsiAssignmentExpression)factory.createExpressionFromText(text, null); - assignment = (PsiAssignmentExpression)CodeStyleManager.getInstance(myProject).reformat(assignment); - assignment.getLExpression().replace(expr); - assignment.getRExpression().replace(binExpr); - setExpr = assignment; - } - parent.replace(setExpr); - } - else{ - if (!processGet) return; - PsiMethodCallExpression methodCall = createGetterCall(usage.fieldIndex, expr); - - if (methodCall != null) { - expr.replace(methodCall); - } - } - } - catch(IncorrectOperationException e){ - LOG.error(e); - } - } - - private PsiMethodCallExpression createSetterCall(final int fieldIndex, final PsiExpression setterArgument, PsiReferenceExpression expr) throws IncorrectOperationException { - String[] setterNames = myDescriptor.getSetterNames(); - PsiElementFactory factory = JavaPsiFacade.getInstance(expr.getProject()).getElementFactory(); - final String setterName = setterNames[fieldIndex]; - @NonNls String text = setterName + "(a)"; - PsiExpression qualifier = expr.getQualifierExpression(); - if (qualifier != null){ - text = "q." + text; - } - PsiMethodCallExpression methodCall = (PsiMethodCallExpression)factory.createExpressionFromText(text, expr); - methodCall = (PsiMethodCallExpression)CodeStyleManager.getInstance(myProject).reformat(methodCall); - - methodCall.getArgumentList().getExpressions()[0].replace(setterArgument); - if (qualifier != null){ - methodCall.getMethodExpression().getQualifierExpression().replace(qualifier); - } - final PsiMethod targetMethod = myNameToSetter.get(setterName); - methodCall = checkMethodResolvable(methodCall, targetMethod, expr); - if (methodCall == null) { - VisibilityUtil.escalateVisibility(myFields[fieldIndex], expr); - } - return methodCall; - } - - @Nullable - private PsiMethodCallExpression createGetterCall(final int fieldIndex, PsiReferenceExpression expr) - throws IncorrectOperationException { - String[] getterNames = myDescriptor.getGetterNames(); - PsiElementFactory factory = JavaPsiFacade.getInstance(expr.getProject()).getElementFactory(); - final String getterName = getterNames[fieldIndex]; - @NonNls String text = getterName + "()"; - PsiExpression qualifier = expr.getQualifierExpression(); - if (qualifier != null){ - text = "q." + text; - } - PsiMethodCallExpression methodCall = (PsiMethodCallExpression)factory.createExpressionFromText(text, expr); - methodCall = (PsiMethodCallExpression)CodeStyleManager.getInstance(myProject).reformat(methodCall); - - if (qualifier != null){ - methodCall.getMethodExpression().getQualifierExpression().replace(qualifier); - } - - final PsiMethod targetMethod = myNameToGetter.get(getterName); - methodCall = checkMethodResolvable(methodCall, targetMethod, expr); - if(methodCall == null) { - VisibilityUtil.escalateVisibility(myFields[fieldIndex], expr); - } - return methodCall; - } - - @Nullable - private PsiMethodCallExpression checkMethodResolvable(PsiMethodCallExpression methodCall, final PsiMethod targetMethod, PsiReferenceExpression context) throws IncorrectOperationException { - PsiElementFactory factory = JavaPsiFacade.getInstance(targetMethod.getProject()).getElementFactory(); - final PsiElement resolved = methodCall.getMethodExpression().resolve(); - if (resolved != targetMethod) { - PsiClass containingClass; - if (resolved instanceof PsiMethod) { - containingClass = ((PsiMethod) resolved).getContainingClass(); - } else if (resolved instanceof PsiClass) { - containingClass = (PsiClass)resolved; - } - else { - return null; - } - if(containingClass != null && containingClass.isInheritor(myClass, false)) { - final PsiExpression newMethodExpression = - factory.createExpressionFromText("super." + targetMethod.getName(), context); - methodCall.getMethodExpression().replace(newMethodExpression); - } else { - methodCall = null; - } - } - return methodCall; - } - - - - private static class MyUsageInfo extends UsageInfo { - public final int fieldIndex; - - public MyUsageInfo(PsiJavaCodeReferenceElement ref, int fieldIndex) { - super(ref); - this.fieldIndex = fieldIndex; - } - } } diff --git a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsViewDescriptor.java b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsViewDescriptor.java index ac5629cb6f1d..550068938de2 100644 --- a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsViewDescriptor.java +++ b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsViewDescriptor.java @@ -1,6 +1,6 @@ /* - * 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,8 +26,11 @@ import org.jetbrains.annotations.NotNull; class EncapsulateFieldsViewDescriptor implements UsageViewDescriptor { private final PsiField[] myFields; - public EncapsulateFieldsViewDescriptor(PsiField[] fields) { - myFields = fields; + public EncapsulateFieldsViewDescriptor(FieldDescriptor[] descriptors) { + myFields = new PsiField[descriptors.length]; + for (int i = 0; i < descriptors.length; i++) { + myFields[i] = descriptors[i].getField(); + } } public String getProcessedElementsHeader() { diff --git a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/FieldDescriptorImpl.java b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/FieldDescriptorImpl.java new file mode 100644 index 000000000000..28488c06e511 --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/FieldDescriptorImpl.java @@ -0,0 +1,79 @@ +/* + * 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.encapsulateFields; + +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiMethod; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Max Medvedev + */ +public class FieldDescriptorImpl implements FieldDescriptor { + private PsiField myField; + private final String myGetterName; + private final String mySetterName; + private final PsiMethod myGetterPrototype; + private final PsiMethod mySetterPrototype; + + public FieldDescriptorImpl(@NotNull PsiField field, + @NotNull String getterName, + @NotNull String setterName, + @Nullable PsiMethod getterPrototype, + @Nullable PsiMethod setterPrototype) { + myField = field; + myGetterName = getterName; + mySetterName = setterName; + myGetterPrototype = getterPrototype; + mySetterPrototype = setterPrototype; + } + + @NotNull + @Override + public PsiField getField() { + return myField; + } + + @NotNull + @Override + public String getGetterName() { + return myGetterName; + } + + @NotNull + @Override + public String getSetterName() { + return mySetterName; + } + + @Nullable + @Override + public PsiMethod getGetterPrototype() { + return myGetterPrototype; + } + + @Nullable + @Override + public PsiMethod getSetterPrototype() { + return mySetterPrototype; + } + + @Override + public void refreshField(@NotNull PsiField newField) { + myField = newField; + } +} diff --git a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/JavaEncapsulateFieldHelper.java b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/JavaEncapsulateFieldHelper.java new file mode 100644 index 000000000000..2d45a929edd1 --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/JavaEncapsulateFieldHelper.java @@ -0,0 +1,346 @@ +/* + * 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.encapsulateFields; + +import com.intellij.codeInsight.generation.GenerateMembersUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PropertyUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.VisibilityUtil; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Max Medvedev + */ +public class JavaEncapsulateFieldHelper extends EncapsulateFieldHelper { + private static final Logger LOG = Logger.getInstance(JavaEncapsulateFieldHelper.class); + + @Nullable + public EncapsulateFieldUsageInfo createUsage(@NotNull EncapsulateFieldsDescriptor descriptor, + @NotNull FieldDescriptor fieldDescriptor, + @NotNull PsiReference reference) { + if (!(reference instanceof PsiReferenceExpression)) return null; + + boolean findSet = descriptor.isToEncapsulateSet(); + boolean findGet = descriptor.isToEncapsulateGet(); + PsiReferenceExpression ref = (PsiReferenceExpression)reference; + // [Jeka] to avoid recursion in the field's accessors + if (findGet && isUsedInExistingAccessor(descriptor.getTargetClass(), fieldDescriptor.getGetterPrototype(), ref)) return null; + if (findSet && isUsedInExistingAccessor(descriptor.getTargetClass(), fieldDescriptor.getSetterPrototype(), ref)) return null; + if (!findGet) { + if (!PsiUtil.isAccessedForWriting(ref)) return null; + } + if (!findSet || fieldDescriptor.getField().hasModifierProperty(PsiModifier.FINAL)) { + if (!PsiUtil.isAccessedForReading(ref)) return null; + } + if (!descriptor.isToUseAccessorsWhenAccessible()) { + PsiModifierList newModifierList = createNewModifierList(descriptor); + + PsiClass accessObjectClass = null; + PsiExpression qualifier = ref.getQualifierExpression(); + if (qualifier != null) { + accessObjectClass = (PsiClass)PsiUtil.getAccessObjectClass(qualifier).getElement(); + } + final PsiResolveHelper helper = JavaPsiFacade.getInstance(((PsiReferenceExpression)reference).getProject()).getResolveHelper(); + if (helper.isAccessible(fieldDescriptor.getField(), newModifierList, ref, accessObjectClass, null)) { + return null; + } + } + return new EncapsulateFieldUsageInfo(ref, fieldDescriptor); + } + + public static PsiModifierList createNewModifierList(EncapsulateFieldsDescriptor descriptor) { + PsiModifierList newModifierList = null; + PsiElementFactory factory = JavaPsiFacade.getInstance(descriptor.getTargetClass().getProject()).getElementFactory(); + try { + PsiField field = factory.createField("a", PsiType.INT); + EncapsulateFieldsProcessor.setNewFieldVisibility(field, descriptor); + newModifierList = field.getModifierList(); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + return newModifierList; + } + + public static boolean isUsedInExistingAccessor(PsiClass aClass, PsiMethod prototype, PsiElement element) { + PsiMethod existingAccessor = aClass.findMethodBySignature(prototype, false); + if (existingAccessor != null) { + PsiElement parent = element; + while (parent != null) { + if (existingAccessor.equals(parent)) return true; + parent = parent.getParent(); + } + } + return false; + } + + public boolean processUsage(@NotNull EncapsulateFieldUsageInfo usage, + @NotNull EncapsulateFieldsDescriptor descriptor, + PsiMethod setter, + PsiMethod getter) { + final PsiElement element = usage.getElement(); + if (!(element instanceof PsiReferenceExpression)) return false; + + final FieldDescriptor fieldDescriptor = usage.getFieldDescriptor(); + PsiField field = fieldDescriptor.getField(); + boolean processGet = descriptor.isToEncapsulateGet(); + boolean processSet = descriptor.isToEncapsulateSet() && !field.hasModifierProperty(PsiModifier.FINAL); + if (!processGet && !processSet) return true; + PsiElementFactory factory = JavaPsiFacade.getInstance(descriptor.getTargetClass().getProject()).getElementFactory(); + + try{ + final PsiReferenceExpression expr = (PsiReferenceExpression)element; + final PsiElement parent = expr.getParent(); + if (parent instanceof PsiAssignmentExpression && expr.equals(((PsiAssignmentExpression)parent).getLExpression())){ + PsiAssignmentExpression assignment = (PsiAssignmentExpression)parent; + if (assignment.getRExpression() == null) return true; + PsiJavaToken opSign = assignment.getOperationSign(); + IElementType opType = opSign.getTokenType(); + if (opType == JavaTokenType.EQ) { + { + if (!processSet) return true; + final PsiExpression setterArgument = assignment.getRExpression(); + + PsiMethodCallExpression methodCall = createSetterCall(fieldDescriptor, setterArgument, expr, descriptor.getTargetClass(), setter); + + if (methodCall != null) { + assignment.replace(methodCall); + } + //TODO: check if value is used!!! + } + } + else if (opType == JavaTokenType.ASTERISKEQ || opType == JavaTokenType.DIVEQ || opType == JavaTokenType.PERCEQ || + opType == JavaTokenType.PLUSEQ || + opType == JavaTokenType.MINUSEQ || + opType == JavaTokenType.LTLTEQ || + opType == JavaTokenType.GTGTEQ || + opType == JavaTokenType.GTGTGTEQ || + opType == JavaTokenType.ANDEQ || + opType == JavaTokenType.OREQ || + opType == JavaTokenType.XOREQ) { + { + // Q: side effects of qualifier??! + + String opName = opSign.getText(); + LOG.assertTrue(StringUtil.endsWithChar(opName, '=')); + opName = opName.substring(0, opName.length() - 1); + + PsiExpression getExpr = expr; + if (processGet) { + final PsiMethodCallExpression getterCall = createGetterCall(fieldDescriptor, expr, descriptor.getTargetClass(), getter); + if (getterCall != null) { + getExpr = getterCall; + } + } + + @NonNls String text = "a" + opName + "b"; + PsiBinaryExpression binExpr = (PsiBinaryExpression)factory.createExpressionFromText(text, expr); + binExpr.getLOperand().replace(getExpr); + binExpr.getROperand().replace(assignment.getRExpression()); + + PsiExpression setExpr; + if (processSet) { + setExpr = createSetterCall(fieldDescriptor, binExpr, expr, descriptor.getTargetClass(), setter); + } + else { + text = "a = b"; + PsiAssignmentExpression assignment1 = (PsiAssignmentExpression)factory.createExpressionFromText(text, null); + assignment1.getLExpression().replace(expr); + assignment1.getRExpression().replace(binExpr); + setExpr = assignment1; + } + + assignment.replace(setExpr); + //TODO: check if value is used!!! + } + } + } + else if (RefactoringUtil.isPlusPlusOrMinusMinus(parent)){ + IElementType sign; + if (parent instanceof PsiPrefixExpression){ + sign = ((PsiPrefixExpression)parent).getOperationTokenType(); + } + else{ + sign = ((PsiPostfixExpression)parent).getOperationTokenType(); + } + + PsiExpression getExpr = expr; + if (processGet){ + final PsiMethodCallExpression getterCall = createGetterCall(fieldDescriptor, expr, descriptor.getTargetClass(), getter); + if (getterCall != null) { + getExpr = getterCall; + } + } + + @NonNls String text; + if (sign == JavaTokenType.PLUSPLUS){ + text = "a+1"; + } + else{ + text = "a-1"; + } + PsiBinaryExpression binExpr = (PsiBinaryExpression)factory.createExpressionFromText(text, null); + binExpr.getLOperand().replace(getExpr); + + PsiExpression setExpr; + if (processSet){ + setExpr = createSetterCall(fieldDescriptor, binExpr, expr, descriptor.getTargetClass(), setter); + } + else { + text = "a = b"; + PsiAssignmentExpression assignment = (PsiAssignmentExpression)factory.createExpressionFromText(text, null); + assignment.getLExpression().replace(expr); + assignment.getRExpression().replace(binExpr); + setExpr = assignment; + } + parent.replace(setExpr); + } + else{ + if (!processGet) return true; + PsiMethodCallExpression methodCall = createGetterCall(fieldDescriptor, expr, descriptor.getTargetClass(), getter); + + if (methodCall != null) { + expr.replace(methodCall); + } + } + } + catch(IncorrectOperationException e){ + LOG.error(e); + } + return true; + } + + private static PsiMethodCallExpression createSetterCall(FieldDescriptor fieldDescriptor, + PsiExpression setterArgument, + PsiReferenceExpression expr, + PsiClass aClass, + PsiMethod setter) throws IncorrectOperationException { + PsiElementFactory factory = JavaPsiFacade.getInstance(expr.getProject()).getElementFactory(); + final String setterName = fieldDescriptor.getSetterName(); + @NonNls String text = setterName + "(a)"; + PsiExpression qualifier = expr.getQualifierExpression(); + if (qualifier != null){ + text = "q." + text; + } + PsiMethodCallExpression methodCall = (PsiMethodCallExpression)factory.createExpressionFromText(text, expr); + + methodCall.getArgumentList().getExpressions()[0].replace(setterArgument); + if (qualifier != null){ + methodCall.getMethodExpression().getQualifierExpression().replace(qualifier); + } + methodCall = checkMethodResolvable(methodCall, setter, expr, aClass); + if (methodCall == null) { + VisibilityUtil.escalateVisibility(fieldDescriptor.getField(), expr); + } + return methodCall; + } + + @Nullable + private static PsiMethodCallExpression createGetterCall(FieldDescriptor fieldDescriptor, + PsiReferenceExpression expr, + PsiClass aClass, + PsiMethod getter) throws IncorrectOperationException { + PsiElementFactory factory = JavaPsiFacade.getInstance(expr.getProject()).getElementFactory(); + final String getterName = fieldDescriptor.getGetterName(); + @NonNls String text = getterName + "()"; + PsiExpression qualifier = expr.getQualifierExpression(); + if (qualifier != null) { + text = "q." + text; + } + PsiMethodCallExpression methodCall = (PsiMethodCallExpression)factory.createExpressionFromText(text, expr); + + if (qualifier != null) { + methodCall.getMethodExpression().getQualifierExpression().replace(qualifier); + } + + methodCall = checkMethodResolvable(methodCall, getter, expr, aClass); + if (methodCall == null) { + VisibilityUtil.escalateVisibility(fieldDescriptor.getField(), expr); + } + return methodCall; + } + + @Nullable + private static PsiMethodCallExpression checkMethodResolvable(PsiMethodCallExpression methodCall, + PsiMethod targetMethod, + PsiReferenceExpression context, + PsiClass aClass) throws IncorrectOperationException { + PsiElementFactory factory = JavaPsiFacade.getInstance(targetMethod.getProject()).getElementFactory(); + final PsiElement resolved = methodCall.getMethodExpression().resolve(); + if (resolved != targetMethod) { + PsiClass containingClass; + if (resolved instanceof PsiMethod) { + containingClass = ((PsiMethod)resolved).getContainingClass(); + } + else if (resolved instanceof PsiClass) { + containingClass = (PsiClass)resolved; + } + else { + return null; + } + if (containingClass != null && containingClass.isInheritor(aClass, false)) { + final PsiExpression newMethodExpression = + factory.createExpressionFromText("super." + targetMethod.getName(), context); + methodCall.getMethodExpression().replace(newMethodExpression); + } + else { + methodCall = null; + } + } + return methodCall; + } + + @NotNull + @Override + public PsiField[] getApplicableFields(@NotNull PsiClass aClass) { + return aClass.getFields(); + } + + @Override + @NotNull + public String suggestSetterName(@NotNull PsiField field) { + return PropertyUtil.suggestSetterName(field.getProject(), field); + } + + @Override + @NotNull + public String suggestGetterName(@NotNull PsiField field) { + return PropertyUtil.suggestGetterName(field.getProject(), field); + } + + @Override + @Nullable + public PsiMethod generateMethodPrototype(@NotNull PsiField field, @NotNull String methodName, boolean isGetter) { + PsiMethod prototype = isGetter + ? GenerateMembersUtil.generateGetterPrototype(field) + : GenerateMembersUtil.generateSetterPrototype(field); + try { + prototype.setName(methodName); + return prototype; + } + catch (IncorrectOperationException e) { + return null; + } + } +} 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 7a11a69e2d82..ea230e3517ce 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java @@ -236,7 +236,7 @@ public class PullUpHelper extends BaseRefactoringProcessor{ if (myIsTargetInterface || info.isToAbstract()) { ChangeContextUtil.clearContextInfo(method); - if (!info.isToAbstract() && !method.hasModifierProperty(PsiModifier.ABSTRACT)) { + if (!info.isToAbstract() && !method.hasModifierProperty(PsiModifier.ABSTRACT) && PsiUtil.isLanguageLevel8OrHigher(myTargetSuperClass)) { //pull as default RefactoringUtil.makeMethodDefault(methodCopy); isOriginalMethodAbstract = true; diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java index 8a88e1c19626..5a086c7a7f2f 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java @@ -159,14 +159,20 @@ public class MoveClassesOrPackagesProcessor extends BaseRefactoringProcessor { @NotNull protected UsageInfo[] findUsages() { - List<UsageInfo> allUsages = new ArrayList<UsageInfo>(); + final List<UsageInfo> allUsages = new ArrayList<UsageInfo>(); + final List<UsageInfo> usagesToSkip = new ArrayList<UsageInfo>(); MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>(); for (PsiElement element : myElementsToMove) { String newName = getNewQName(element); if (newName == null) continue; final UsageInfo[] usages = MoveClassesOrPackagesUtil.findUsages(element, mySearchInComments, mySearchInNonJavaFiles, newName); - allUsages.addAll(new ArrayList<UsageInfo>(Arrays.asList(usages))); + final ArrayList<UsageInfo> infos = new ArrayList<UsageInfo>(Arrays.asList(usages)); + allUsages.addAll(infos); + if (Comparing.strEqual(newName, getOldQName(element))) { + usagesToSkip.addAll(infos); + } + if (element instanceof PsiPackage) { for (PsiDirectory directory : ((PsiPackage)element).getDirectories()) { final UsageInfo[] dirUsages = MoveClassesOrPackagesUtil.findUsages(directory, mySearchInComments, @@ -186,6 +192,7 @@ public class MoveClassesOrPackagesProcessor extends BaseRefactoringProcessor { } } + allUsages.removeAll(usagesToSkip); return UsageViewUtil.removeDuplicatedUsages(allUsages.toArray(new UsageInfo[allUsages.size()])); } @@ -411,23 +418,30 @@ public class MoveClassesOrPackagesProcessor extends BaseRefactoringProcessor { @Nullable private String getNewQName(PsiElement element) { final String qualifiedName = myTargetPackage.getQualifiedName(); - final String newQName; - final String oldQName; if (element instanceof PsiClass) { - newQName = StringUtil.getQualifiedName(qualifiedName, ((PsiClass)element).getName()); - oldQName = ((PsiClass)element).getQualifiedName(); + return StringUtil.getQualifiedName(qualifiedName, ((PsiClass)element).getName()); + } + else if (element instanceof PsiPackage) { + return StringUtil.getQualifiedName(qualifiedName, ((PsiPackage)element).getName()); + } + else { + LOG.assertTrue(false); + return null; + } + } + + @Nullable + private String getOldQName(PsiElement element) { + if (element instanceof PsiClass) { + return ((PsiClass)element).getQualifiedName(); } else if (element instanceof PsiPackage) { - newQName = StringUtil.getQualifiedName(qualifiedName, ((PsiPackage)element).getName()); - oldQName = ((PsiPackage)element).getQualifiedName(); + return ((PsiPackage)element).getQualifiedName(); } else { LOG.assertTrue(false); - newQName = null; - oldQName = null; + return null; } - if (Comparing.strEqual(newQName, oldQName)) return null; - return newQName; } protected void refreshElements(PsiElement[] elements) { |