diff options
author | Tor Norbye <tnorbye@google.com> | 2013-12-20 09:14:04 -0800 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2013-12-20 09:14:11 -0800 |
commit | 8668e1be0891658129cbc8f0965380f702c26755 (patch) | |
tree | 9facfcf805e92469be9bab9f274b1b383c93ac79 /java | |
parent | dabd634b4b52246dc992371eecb7e1e214463cff (diff) | |
download | idea-8668e1be0891658129cbc8f0965380f702c26755.tar.gz |
Snapshot 020d29497847701e84e383d965abf543b80758e2 from idea/133.370 of git://git.jetbrains.org/idea/community.git
020d294: platform: incompatible KTerm option stripped
589c8be: ui: correct icon for facet editor panel
00b8db5: skip invalid highlighters (EA-37197) - 8K reports! (cherry picked from commit 3688a79) [r=Peter.Gromov]
663de5b: IDEA-114952 Eclipse code style import: would be nice to remember imported file location (URL fix for Windows) (cherry picked from commit 7f1b705)
fd13ff8: IDEA-116071 (Field can be final inspection change) (cherry picked from commit e1eab58)[CR-IC-3389]
ae3b411: IDEA-116508 ("Local variable or parameter can be final" inspection use generates uncompilable code not extracting a really finalizable variable) (cherry picked from commit 49639e8)[CR-IC-3388]
e31eafc: EA-52123 (IAE: InvertBooleanHandler.invoke) (cherry picked from commit 18e2e69)
b318047: 2x more compact mapping storage for 7bit ascii paths [r=Eugene.Zhuravlev] (cherry picked from commit 2f10822)
42fa68e: IDEA-117378 Privilege escalation via JetBrains products by local attacker (cherry picked from commit 81b56c6)
87e3a49: IDEA-118063 Gradle: cosmetic fix 'Add gradle plugin' action: 'Choose plugin' popup has lots of not clickable links (cherry picked from commit ca4f7bc)
1245a78: IDEA-117792 Gradle Run/Debug Configuration: support adding Gradle specific parameters; review - http://crucible.labs.intellij.net/cru/CR-IC-3727
8558b99: 13.0.2 with EAP
997edcb: no smart icons and no parameter info in power save mode (cherry picked from commit 4bb3242)
bdd56c0: [^jeka] tolerate mysterious groovy class file corruption
a346506: IDEA-118397 Resume build not working (cherry picked from commit ea2b802) +review CR-IC
a659297: IDEA-118245 Retain the last used command line in the Execute Maven Goal dialog (cherry picked from commit 26a7d57) +review CR-IC
a604811: IDEA-118102 Maven: artifacts name not properly generated from pom in IDEA 13 (cherry picked from commit e610603) +review CR-IC
a8ffcf9: IDEA-118053 Editor "deprived of mind" when editing settings.xml (cherry picked from commit ed529d5) +review CR-IC
0e9a065: IDEA-78508 [Maven] Good Code Red with empty variables in classifiers (cherry picked from commit 0831af1) +review CR-IC
cbd34cb: IDEA-116921 Run configuration can't resolve test dependency when "Resolve workspace artifacts" ticked on. (cherry picked from commit d06f31a) +review CR-IC
75e374a: Fix for IDEA-116940 @formatter off still generating braces [CR-IC-3478] (cherry picked from commit 3340beb)
1f6f81f: avoid unconditional trace properly (cherry picked from commit 2e72fcc)
5f45643: Compilation fix
a4749db: IDEA-118292 (process idea.properties in declaration order)
679e1c4: IDEA-118111 (OpenJDK 6 check made strict)
950225b: restore classes in nav bar (IDEA-118168)
cfe1124: NPE
0a41d99: method may be static: process default methods (IDEA-118272)
6ff67d9: redundant cast: ensure that temp variable would have unique name (IDEA-118197)
9549258: distinct prover: distinguish types when type parameter has bounds (IDEA-118037)
0dcb258: show param info: highlight overload vararg method
c40975b: method references: smart completion to filter by return type
319017d: disable lambda completion after inserted qualifier
ed361ec: do not register fixes which need editor in batch mode (IDEA-116248)
30cba59: EA-52652 - NPE: ExceptionUtil.getUnhandledExceptions
c9199b7: redundant type args: process nested calls (IDEA-117945)
fad3ead: IDEA-117989 JUnit: Run/Debug java test output "scroll to stacktrace" not working as expected
c9d58cc: IDEA-117911 Delegate methods duplicate @Override
35afc12: generate javadoc: search for modules under progress
bf0ec72: IDEA-117883 make <--tooltip end--> logic work in Inspections View; provide additional tooltip bounds
056b529: new inference: propagate outer method to constraints, initial (IDEA-117803)
cd65706: IDEA-117827 Invalid "ambiguous method call" error
8251b5d: IDEA-117780 Bad code is green: non-static class T cannot be referenced from a static context
4a1ae2f: restore suppressions (IDEA-117763)
b7003c6: pull up: ignore conflicts coming from access object when it is also moved (IDEA-117671)
282c332: remember different working dirs for rerun (IDEA-116110)
8224a17: scope to check for cheap search (IDEA-117665)
b2affde: refactoring high level listeners (IDEA-115905)
a2ae64e: NPE
f75829b: extend local scope a set of containing files as visitors expect file level (IDEA-117649)
c72c42f: tests notification: separate not started notification from ignored when no 'not started' tests were detected (IDEA-116825)
5a0aebc: suspicious names: highlight only variable name (IDEA-116475)
62ba24a: disable introduce variable from part of literal expression which is not a string
740bbf2: testng: ignore default annotations attributes (IDEA-117575)
52c384c: add explicit arguments: eliminate wildcards (IDEA-106741)
31e57cc: check lambda return values during constant&conditions (IDEA-117420)
c8ff7ea: javafx: allow to configure custom manifest attributes (IDEA-115252)
99b89cc: IDEA-117314 Can not compile Java project with Eclipse dependencies storage format
528f2d5: introduce variable inside lambda: do not step out of lambda block
48cb2be: IDEA-117252 Extract variable bug
8724806: IDEA-113339 "replace with method reference" ignores side effect of expression: ignore any new expressions in qualifiers
6f6d61b: lambda -> method ref: do not convert if resulted ref would be ambiguous (IDEA-116964)
d9a89a1: EA-52426 - NPE: JavaDocInfoGenerator.generateSuperMethodsSection
df01945: IDEA-118264 Rearrange Entries stopped working in Intellij 13
5e7d560: files compiled on first round may require additional recompilation on the next round (second part for IDEA-116914) constant search on the IDE side rewritten: only direct dependencies are returned for each search round; all transitive dependencies will be additionally handled by make
4792865: handling cases when added class hides imported class with the same short name (IDEA-116914 Incremental compilation of Java project fails)
e99d464: correct check
ea90776: safely skipping some invalid usages
3a16b61: proper synchronization
0c9c72e: IDEA-117249 Optimize make's constant search algorithm, so that read action is not held for long time
f19231c: do not search usages of removed constant fields in injected PSI
d6ef061: Merge branch '133' of git.labs.intellij.net:idea/community into 133
fa65f8e: IDEA-35996 Ant integration: provide more informative message in case ant file execution is stopped due to unknown command line argument
9519530: IDEA-117904 Ant integration: running: with an error (javac) the result is reported as "successful": perform all status calculations after all messages are processed
5a9f9a8: IDEA-111702 Java Rearranger illegal forward reference on fields rearrangement [CR-IC-3034] (cherry picked from commit 7f01bcd)
a2dd3a6: IDEA-115786 Allow the number of Maven threads to be specified (cherry picked from commit 9d05ff2) +review CR-IC
abfd9a5: IDEA-114418 (Grails SDK of an dependency) -Dgrails.disable.structure.update=true should work for JDK synchronization. (cherry picked from commit 009ca28) +review CR-IU
491ceb6: IDEA-96723 Java Rearranger deletes blank lines in field declarations (cherry picked from commit 15869e7)
85fe89f: IDEA-118159 "Search Everywhere" inconsistent api on ItemPresentation (cherry picked from commit 9729ea9) [r=Konstantin.Bulenkov]
bcf528b: revert platform fix for PY-6095, apply Python specifix fix instead (cherry picked from commit 0dfae8b)
fec8fe7: IDEA-117864
930439c: cosmetics
6c1df41: IDEA-108838 Wrong code when introducing variable in injection (cherry picked from commit f119c2e)
2a40aeb: Merge remote-tracking branch 'origin/133' into 133
d92cdcc: IDEA-117391 (annotation highlighting fixed)
05a20ae: IDEA-117772 (start application loading in EDT)
ef18d70: DevKit: refine DOM stubs + test (cherry picked from commit 84d8e52)
15d7962: IDEA-117583 DevKit: highlight <idea-version> "min"|"max" as deprecated (cherry picked from commit ce277a1)
be71e9a: cleanup, update "since-build" (cherry picked from commit f56ca26)
e9aa79b: IDEA-117573 DevKit: highlight <vendor> "logo" as obsolete (cherry picked from commit d552ee4)
d5d86be: EA-52563 - assert: ChooseModulesDialog$MyTableCellRenderer$.customizeCellRenderer (cherry picked from commit d24d279)
009d144: CodeInsightTestUtil#doIntentionTest(): remove Throwable declaration (cherry picked from commit d7e8e2a)
e543b44: lazy class loading for PtyProcess (r=Eugene.Zhuravlev), 2 (cherry picked from commit 85700e4)
edd9c56: save / load per project key hash codes (cherry picked from commit c847d67) [r=Eugene.Zhuravlev]
eff72da: avoid garbage creation in JDK7 due to calling StringBuilder.toString() that copies buffer now (cherry picked from commit 03f7413) [r=Peter.Gromov]
40c73d4: no need to create strings of PsiFile's Text when we can avoid it or use charsequence (cherry picked from commit d8ec59b) [r=Peter.Gromov]
10c479c: introduced cvs.roots.refresh.uses.vfs property (true by default) and uses its value to refresh cvs roots after update using vfs to avoid performance problems (IDEA-112132) (cherry picked from commit 1958e9a) [r=Peter.Gromov]
8cac2e5: - detect proper encoding for html5's <meta charset="charsetname"> - [performance fix] avoid (light) parsing of html content if there is no charset\s*= pattern inside the string (cherry picked from commit 2f4be38) [r=Alexey.Kudryavtsev]
cee6644: IDEA-78206 Constructing 'mailto' link -> cannot resolve file 'mailto' (cherry picked from commit 3166c04) [r=Konstantin.Ulitin]
98571ff: Cyclic Expand Word leaves word highlighted (IDEA-115727) (cherry picked from commit 29bb231) [r=Peter.Gromov]
31fe1a1: refixing IDEA-57940 : the variants from other editors are suggested AFTER finishing variants from current file (cherry picked from commit e76fe51) [r=Peter.Gromov]
e3975be: avoid allocating sun.nio.cs.US_ASCII$Decoder when converting byte[] to String
1053bdb: don't create TIntArrayList(DEPTH_LIMIT) before we have clear indication that we might have a loop (parentId >= id) (cherry picked from commit 5478fdf) [r=Alexey.Kudryavtsev]
364e80e: avoid unconditional trace (cherry picked from commit 2e72fcc) [r=Alexey.Kudryavtsev]
70980d8: don't call toString() without need to avoid garbage (cherry picked from commit 75c030c) [r=Alexey.Kudryavtsev]
466dc64: Apply again "update stubs per filetype reverted for 133 branch"
3f66295: Apply again "IDEA-113684 Soft wraps insert additional spaces"
028b3ae: Darcula: combobox as cell renderer/editor fixes
e96975a: fix default size of SourceMapInspector window (cherry picked from commit a64047e)
edfb4da: if IDEA sees text/plain and extension .java, perhaps it should infer that it's actually Java, because not everyone will set up their HTTP servers with language-specific mime types? (Particularly when following a URL to a source file in a sourcemap.) +review (cherry picked from commit 5ea95e3)
6162222: fix ClassCastException: com.intellij.openapi.fileEditor.FileEditorState$1 cannot be cast to com.intellij.openapi.fileEditor.impl.text.TextEditorState (cherry picked from commit 44f0697)
6c8dbc0: update progress on test done (finished, failed, or ignored), not on test started (cherry picked from commit dbcb907)
a4038dd: REGISTERED state added (cherry picked from commit 08677f9)
bf0da3a: fix PersistenceRenameTest blinking: inconsistent @NameValue placement and random methods order in DomGenericInfo
1f08879: PsiBuilder/GPUB: zero-length token parsing support (lexer-based macros)
352056d: EA-52484 - IOOBE: ConsoleHistoryModel.getHistoryPrev
21ab06f: EA-52027 - assert: TextRange.<init>
b452663: IDEA-116383 cannot reconnect Some RuntimeException contains not serializable class 'org.apache.maven.model.building.DefaultModelProblem'. So IDEA throw java.rmi.UnmarshalException caused by java.io.NotSerializableException. (cherry picked from commit 9f7fb6c) +review CR-IC
a4e9447: Revert "IDEA-113684 Soft wraps insert additional spaces"
231adec: Revert "update stubs per filetype reverted for 133 branch"
d62a526: use method instead of manual hack
cae16e2: better combobox rendering on aqua: no focus ring around combo button, fixed 1px size difference
7d9b58c: fix TextFieldWithHistory rendering on mac
95d40df: determine tag end by doctype #WEB-2229 fixed
556c3bc: lazy class loading for PtyProcess (r=Eugene.Zhuravlev) (cherry picked from commit 96c8bca)
749d89f: RUBY-14672: better name for gracefulProcessTermination() (reviewed by Dennis Ushakov and Sergey Simonchik ) (cherry picked from commit 908538b)
dd5dd11: RUBY-14672: we need to send SIGINT to Ruby debugger twice (reviewed by Dennis Ushakov and Sergey Simonchik ) (cherry picked from commit 4546732)
3c01a72: Merge remote-tracking branch 'origin/133' into 133
6378e77: [git] IDEA-118265 Fix showing Git Branches menu
b9446e2: close process's input stream after process termination (cherry picked from commit e962648) CR-WS-272
c8fbe68: support Windows soft kills using runnerw.exe in KillableColoredProcessHandler (cherry picked from commit 77e0f1a) CR-IC-3459
988c990: fix showValuePopup — incorrect scrolling (cherry picked from commit 594785c)
1f67166: IDEA-105450 Attribute id in OSGI reference element not allowed: XmlHighlightingTest.testXhtmlSchemaHighlighting fixed (cherry picked from commit 69daed6)
eb3a323: IDEA-105450 Attribute id in OSGI reference element not allowed: get schemaLocation from import tag (cherry picked from commit ec44bbd)
8bb9587: IDEA-105450 Attribute id in OSGI reference element not allowed: namespaces from standard resources should be considered relevant (cherry picked from commit d30684d)
a129c6c: IDEA-84166 Support "CTRL+H" on class in .xml file (cherry picked from commit da3cbf3)
7162d4b: update stubs per filetype reverted for 133 branch
377bf70: IDEA-113684 Soft wraps insert additional spaces (cherry picked from commit 0e1c820)
643cd5d: use direct call to storage.resize() so that IOException is not masked with RuntimeException (IDEA-118107)
2e7c85f: Plugin for IDEA 133.286 3.0.1 EAP CE
f75f35e: Merge branch '133' of git.labs.intellij.net:idea/community into 133
9186d35: PyCharm 3.1
58936a1: add create method
ecf556d: do nothing if state didn't change
dcfbfb5: IDEA-115859 Presentation mode is broken
1d6443d: Javascript tests fixed, IDEA-113977 Formatter: caret is moved on next line if closing brace has wrong indent [CR-IC-3034] (cherry picked from commit dd55e70)
b75041b: Merge branch '133' of git.labs.intellij.net:idea/community into 133
2a74e83: Pty lib updated - run in console mode.
390900e: Guava and Pty4J libraries dependencies.
10a39d8: Contains in branches feature implemented for mercurial log.
37a14b0: Added logging.
9355a2b: improved user experience with run configuration producers
78e57f9: Better multiline code handling in console.
fc7702f: Correct test data path.
6bba62d: Detect SQL fragments only in the beginning of string literals
ba5ff19: Fixed LiteralTextEscaper.getOffsetInHost() for partial ranges inside host that contain escapes
df0c579: Added caching of decoded fragments of string literals
f93a871: Fixed detecting file references in Python strings without delimiters
01bf006: Removed unused PyStringLiteralExpression.iterateCharacterRanges()
147ed7a: Switched to new string value iteration in Python file references inside string literals
f8e775c: Use Pair instead of a custom class
0106a10: Switched to new string value iteration in Python spellchecker
69ac8c5: Added PyStringLiteralExpression.getDecodedFragments()
d703ca5: reverted module type from plugin_module to java_module for localization and rest
2cb9a61: fixed tests since we don't propose to make static decorated method
d6ed1d7: fixed PY-10998 Wrong highlight in rst (restructured texts) for headlines
5511e2f: Fix NPE.
9f0c134: Don't break compatibility (PY-11499).
f80fc2e: fixed PY-11500 False positive in method may be static inspection for decorated methods
0bfaaf2: fixed PY-2984 Surround with try/except reformats entire file
0ed12da: args can be immutable (PY-11465).
1bb8318: fixed PY-11435 Can't run script by context menu action if it has method named test
0336898: Fixed detection of the largest string literal for right parts of '%' operator
cb5714e: fixed PY-11452 tcunittest errors with single-character failure message
2503a60: fixed test data
16aa28c: fixed PY-11476 No error given for mismatched accolade and squarebracket
403b937: Allow to run processes with PTY.
4740054: Added comment-based language injector for Python
f56fecc: fixed tests
45a824c: Fixed un-inject language availability for temporary Python injections
ea707eb: Method renamed.
4b349d3: Extracted PyInjectionBase.registerInjection
909a31d: Don't inject any language into percent-based Python formatting even without formatting operator (PY-10771)
b928248: Fixed SQL select IntelliLang pattern (PY-10926)
55239bf: If command executed but is incomplete and more lines are needed prompt shouldn't be changed to ordinary one in this case.
a061c7e: Fix modified console options modified after creation.
52b6eb3: Jython doesn't support 'exec' symbol in interactive console.
1213be2: PyConsole: correctly indent after execution of incomplete multi-line string.
38b4e20: Fixed execution of incomplete multiline code fragments.
5306cfb: First evaluate more then add to queue.
4f18cfe: Simplified.
9688ef7: Attribute renamed.
10a0e30: NotNull annotation.
5e5c546: Fixed IPython and debug console broken by console execution model changes.
e53607e: Fixed write lock assertion.
78ea78d: Execute multi-line code fragments by runsrouce with 'exec' option instead of one line by one (PY-10769).
0dcf990: Cleanup.
9f4dca96: Broken indentetion in console fixed (PY-10776).
3c4550e: Fixed saving of env in console settings. Mappings format saving changed.
699255f: Fixed working directory setting in console settings.
9b98ce9: Fixed saving path mappings in console settings (PY-9855).
14fbafd: Don't ask to reconnect remote interpreter in case of fail as it never helps but causes problems (PY-10590).
f8a096a: Support for temporary and configuration-based IntelliLang injections in Python (PY-10983, PY-10721)
5def9d3: fixed http://youtrack.jetbrains.com/issue/PY-2953
e6a24df: fixed PY-11394 "no tests were found" with django 1.6 DiscoverRunner
1fb4a8a: used consistent name prefix
923f8c0: fixed PY-11415 GAE: Lazy Handler reference is not updated when moving to other module
0a3c840: fixed PY-9967 App Engine: do not resolve to installed to interpreter library
ea42fbf: [log] Fix showing dot in the root table header
decac91: [log] Fix background of the details panel content (cherry picked from commit 2ad2cba)
224a2be: [log] fix name of variable
f79c2e4: [log] IDEA-115675 IDEA-116040 Fix table columns sizing
668c021: [log] IDEA-117500 Don't repaint branches panel on every updateUI
ed4a8ca: [log] IDEA-117500 Optimize grouping of branch references
a98e6c8: [git] Don't modify the unmodifiable collection (cherry picked from commit 007dc0d)
9321b17: [git] IDEA-117500 Don't copy, just wrap in unmodifiable
f3cd826: [git] remove unused method
d7db0fc: [log] Separate loading indicator for "Contained in branches"
ab8606f: [log] Fix "Containing branches" for filtered list & for Mercurial
c190668: [git] Move & rename method to get branches to GitBranchUtil for reuse (cherry picked from commit f78700e)
0ae4458: [git] Simplify method to get branches: use branch names.
423dbc6: IDEA-117936 IDEA13 fails to stop at breakpoint inside advised method
4587a46: IDEA-117613 Gradle: tool window is missing after the update, safe check for newly created project added
18e44f3: IDEA-117613 Gradle: tool window is missing after the update review: http://crucible.labs.intellij.net/cru/CR-IC-3629
b9b4c6c: fixed IDEA-111701 Emacs: pressing Ctrl+k several times should add lines to muti-line buffer (regression for IDEA-18764, broken in IDEA-111275)
a843386: we must not use getKnownFileTypeOrAssociate on navigate (cherry picked from commit 476b30d)
cf363b6: fix actionSystem.fixLostTyping.description (cherry picked from commit caf3ece) CR-IC-3481
4dfe767: IDEA-117548 Bad function parameters highlight (cherry picked from commit d4507c9)
b83ac23: fix assertion (cherry picked from commit 5743c3c)
f7e5eeb: WEB-10231 first navigation to http file doesn't open desired location (cherry picked from commit 384f8f9)
fe39b87: wait smart mode checks for isReadAccessAllowed too, so, we must not call it (cherry picked from commit a5dd92c)
f4c9d17: optimization — check isEmpty (cherry picked from commit 44727c2)
cd8fb58: VmFileEditor — prepare to fix postponed navigation problem in our HTTP file editor. VmFileEditor supports postponed navigation. (cherry picked from commit db4ca37)
c669320: "Run in background" option from now on means "show build messages immediately" rather than "execute with modal dialog"
d83aedd: don't generate large substrings when creating CompletionResultSet [r=Peter.Gromov]
87ad24b: 13.0.1
14361cd: avoid easy garbage java.util.ArrayList$Itr: 1,720,417,512 (1%) bytes in 71,684,063 (2%) objects (avg size 24 bytes) java.util.ArrayList.iterator: 1,720,392,864 (99%) bytes in 71,683,036 (99%) objects com.intellij.openapi.projectRoots.impl.ProjectJdkTableImpl.findJdk: 938,831,640 (54%) bytes in 39,117,985 (54%) objects com.intellij.openapi.editor.impl.ComplementaryFontsRegistry.getFontAbleToDisplay: 218,420,520 (12%) bytes in 9,100,855 (12%) objects (cherry picked from commit 9207b87) [r=Peter.Gromov]
41efe97: look for xml properties in files with xml file type only (cherry picked from commit b6ae811) [r=Dmitry.Avdeev]
ea2590e: WEB-10191 Weird field in the Configure NodeJS Modules Sources (cherry picked from commit 0f61ced) http://crucible.labs.intellij.net/cru/CR-IC-3556
a2b39c2: Gradle: fix dependencies scope merge IDEA-117556 Gradle custom provided configuration added with compile scope IDEA-117601 Gradle integration ignores scopes.TEST.plus in build.gradle (cherry picked from commit f80d692) Safe hotfix, the code works in a separate process (in gradle daemon, not in IDE process)
ce53010: External system: build files modification triggers threads continuously if "auto-import" feature enabled review- http://crucible.labs.intellij.net/cru/CR-IC-3533
4d9ae0c: Gradle: fix dependency scope merge to respect artifact classifier option related bug - IDEA-117627 Transitive dependencies missing from imported Gradle project Safe hotfix, the code works in a separate process (in gradle daemon, mot in IDE process)
d9c3f83: IDEA-117669 gradle multi-module project executing subtask uses wrong gradle version review - http://crucible.labs.intellij.net/cru/CR-IC-3564
87819e2: Gradle: IDEA-116880 Intellij 13 doesn't auto-save files before Gradle task (cherry picked from commit e5c53c6)
5b87b39: Gradle: fix MultipleRepositoryUrlsInspection to operate on gradle-relevant files only (cherry picked from commit 95fbdc9)
1c2f07c: IDEA-117432 Do not fail while resolving client factory for upgrade if "other factory" is configured incorrectly (cherry picked from commit 0694e5d)
d11b435: IDEA-117432 Do not fail while resolving client factory for checkout if "other factory" is configured incorrectly (cherry picked from commit 6242d70)
db15422: Branch information checks moved to appropriated separated methods. (cherry picked from commit 9492982)
6f85df3: Method name simplified (cherry picked from commit 0924c2b)
16e2328: IDEA-115906 Throwable ; IDEA-117401 IAE fixed
eedd7fe: HEAD branch filter in new log fixed (cherry picked from commit 7793e6f)
a787eb2: VcsRootDetector and NotifierError tests fixed (there were .git in T ot tmp dir above, so appropriate checker found its root,then error)
ddc643d: remove outdated and buggy (in case of library code) property java.debugger.xBreakpoint.onlyIfHasFacets (cherry picked from commit 5b7f60f)
ab9cce8: CR-IC-3511 CFR-63806 (cherry picked from commit e800ade)
d3e739f: introduce newUrl (cherry picked from commit bb94f47)
5009fbf: VisualizeScriptSourcemap action (cherry picked from commit 2694a1f)
2051c1e: cleanup (cherry picked from commit 30d4cdf)
586ef62: Merge remote-tracking branch 'origin/133' into 133
3a93fee: rollback IDEA-117378. It will be available in 13.0.2
d72ed2a: IDEA-117227 load imports from stubs [^Peter]
5568b0d: Groovy: injection in command expression [^Peter]
b0ef47e: IDEA-117389 Groovy: Introduce constant from string part [^Peter]
7076f89: IDEA-117227 stubs for Groovy imports [^Peter]
605a0a9: IDEA-117390 'IntelliJIdeaRulezzz' in Code Completion [^peter]
ac4417e: fix testdata
8607b4d: IDEA-116547 optimization in reassigned vars check [^peter]
1e7c610: WEB-10019 Don't show emmet preview after simply dot (cherry picked from commit 127560f)
4b36aad: WEB-9986 CSS: fuzzy search shows turned off abbreviations (cherry picked from commit 56e0385)
4b4958e: WEB-10017 New "Surround with emmet" popup breaks usability (cherry picked from commit 8bdc013)
0bd5b71: automatically starts rebuild if java builder caches are corrupted (IDEA-117024) [rev by Jeka]
f536c49: Merge remote-tracking branch 'origin/133' into 133
81b56c6: IDEA-117378 Privilege escalation via JetBrains products by local attacker
633cd5e: a temporary workaround for HiDPI on Windows/Linux
b7a8a38: Local VCS tests quick fix (ignore temp. FS)
eecd3d1: make history almost unlimited
72de836: no delay after tab or escape
96b5a46: re-create components on every call (laf change fix)
9aa347b: Extracted Python path walking and fixed broken symlink check (PY-10534)
66b3393: differentiate between Sun and Oracle VMs
6b27a51: fixed silent installation mode.
0e4a0fc: IDEA-117378 Privilege escalation via JetBrains products by local attacker IDEA-113862 Confusing Run as dialog
a7300cd: [^maxim] FrequentEventDetector: log outside of synchronized (IDEA-117426)
9d0b588: [^nik] GroovyHotSwapper: use FileTypeIndex
3228a63: [^nik] cache GroovyHotSwapper.containsGroovyClasses (IDEA-116851)
57ff2da: IDEA-103199 Undo: UTF problem (after-review improvements) (cherry picked from commit 0a0aecf)
75ed596: IDEA-103199 Undo: UTF problem (cherry picked from commit ea49ecf)
0a705a8: correct definition of "oracle vm" for java 6
7464e2f: can not clear JarFileHandler caches (e.g. on JDK 7) -> no logging (cherry picked from commit 5012a9b) [r=Alexey.Kudryavtsev]
299f014: IDEA-117498 Caret locks up after using ctrl+tab to switch editors [r=Peter.Gromov] (cherry picked from commit 38f2f05)
99b71dc: IDEA-117494 133.193: Importing grails modules not labeled as grails enabled +review CR-IU (cherry picked from commit 588cd01) reviewer: Peter Gromov
48ce506: do not auto-switch current suspend context if a new thread with suspenPolicy=thread hits a breakpoint (IDEA-116160)
64dc9f5: CR-IC-3489 restore old API
f1dcd4c: Merge remote-tracking branch 'origin/133' into 133
4b41e83: [log] IDEA-117365 Expect "empty" git tag; protect against errors
725c360: [log] Register disposable right away, not after initialization (cherry picked from commit 1e48680)
265d0df: EA-51913 - assert: DomNamespaceKeyIndex.hasStubElementsWithNamespaceKey (cherry picked from commit 6763822) CR-IC-3472
42ecb1a: CR-IC-3471 (cherry picked from commit b213f10)
89ee113: finalize consts (cherry picked from commit 73b245e)
d033d07: gwt, ability to debug — one idea module to many gwt modules (cherry picked from commit 8086f92)
056f905: NullFileEditorState +review (cherry picked from commit 561c8d1)
ca7af60: overrides (cherry picked from commit aaa236a)
4f2af9c: CR-IU-366 (cherry picked from commit 40ae21d)
c8c0d46: Problem — we use short gwt module name (Hello) instead of output name (hello, rename-to specified in Hello.gwt.xml). 1) if rename-to specified, url will be http://localhost:9876/sourcemaps/{rename-to} rename-to=“hello” => http://localhost:9876/sourcemaps/hello 2) if rename-to is not specified, url will be http://localhost:9876/sourcemaps/{qualified name} com.google.gwt.sample.hello.Hello => http://localhost:9876/sourcemaps/com.google.gwt.sample.hello.Hello
40f41b5: IDEA-116260 ISE: RPC handler object "AddOnlineUser" not found at com.intellij.ide.XmlRpcServerImpl.process (cherry picked from commit 5aa9b8e)
3265387: enable all lafs by passing a special registry key
bf2b0c6: Rename "Java" -> "JVMOptions" so MacOS doesn't require java 1.6 download from Apple.
c825894: [log] Make fields volatile
3cc0a09: [git] IDEA-116690 Fix "Select in Git Log" from File History
8b85de3: fixing IDEA-117328 java.lang.NoSuchMethodError: com.sun.tools.javac.util.Paths.clearPathExistanceCache()
7e1850e: Merge remote-tracking branch 'origin/133' into 133
f2aed4c: IDEA-117347 Search Everywhere popup is too wide
3675b82: merging ConcurrentMapFactory and ContainerUtil
98ef79b: fix Url equality (scheme) (cherry picked from commit e668634)
290e4a4: fix NPE — url could be in any form, so, parsed can be null (cherry picked from commit ec22c2e)
f90eaba: allow V8 map on IBM JDK 1.7
845ffae: do not disable "ext.dirs" location, because IBM jdk stores some of its essential jars there
5278615: EA-52516 - IAE: HighlightUsagesHandlerBase.addOccurrence
cae4139: EA-52505 - NPE: MethodCandidateInfo.getPertinentApplicabilityLevel
9b6b81e: default concurrency level upper limit
91cefef: encapsulation of factory's implementation details
1081168: IDEA-117298 Darcula&IntelliJ on Windows: Inspection description is too small in Settings
7799dc3: IDEA-117095 Goto File: checkbox 'include non-project files' is remembered between invocations [r=Anna.Kozlova] (cherry picked from commit 7cf6caa)
8eecc0f: all code in "util" module to create CHM implementation via dedicated factory (see IDEA-116404 Java code compilation does not work with IBM JDK)
81ae633: [Filechooser sheets] IDEA-102449 Mac OS + JDK 1.7: dialog sheets go to background if focus is moved from IDEA and then back
ea058b0: fix NPEs
8fbca43: Remove broken dependency on 'markdownj' from tasks-core module
5c1098b: IDEA-117258 IntelliJ theme: selected tabs in Debugger and in Run <application server> views get black color
5e02eb3: IDEA-116558 Update state transition requests for JIRA REST API 2
c2f531a: "read access" assertion and NPE fixes
ea4f96b: fix "read access" assertion
787438f: IDEA-117265 java.lang.ClassCastException: com.intellij.psi.impl.source.tree.java.PsiParenthesizedExpressionImpl cannot be cast to com.intellij.psi.PsiCallExpression
99ae1f5: NPE on invalid expressions
ffc7fa5: IDEA-115953 Editor: Line Spacing < 1.0 no longer works (reviewed by Roman Shevchenko)
886b675: External system: add support for different naming of external entities within IDEA models. E.g. external lib name: 'somelib' -> IDEA lib name: 'Gradle: somelib'. external module name: 'some/module' -> IDEA module name: 'some_module'. (cherry picked from commit bb941b0)
0634d95: enable abbreviations (cherry picked from commit 0ecc836)
1dc77a9: more searchable options
31750db: fix history and symbols 'More' action
bc4db67: Merge remote-tracking branch 'origin/133' into 133
84f584a4: add new actions
5a49390: change action place to Main Menu
4a50f96: don't use smart search for files (don't use space as a separator)
93dd505: ready to nulls (EA-52470 - IAE: TypeCompatibilityConstraint.<init>)
174531a: EA-52436 - IAE: PsiElementFactoryImpl.createType
e58f16d: IDEA-115412 Diff window is minimized after the appearance (cherry picked from commit b2307d0)
8146462: IDEA-117059 (error reporting in updater fixed)
be1c105: NPE in mouse handler
a460658: IDEA-111388 Built-in server not "available external" — it is unclear that port number must be also changed (cherry picked from commit 6ccdae5)
dfdaaae: continue WEB-9968 Dart: ClassCastException when debugging web application in Dartium (cherry picked from commit c19e163)
ee28c75: newHttpUrl — authority must be NotNull (cherry picked from commit a708a6e)
01efd39: NetUtils.tryToFindAvailableSocketPort (cherry picked from commit fa39c70)
ca466c8: introduce Urls.newUri, prepare to fix WEB-9968 Dart: ClassCastException when debugging web application in Dartium (cherry picked from commit 4ecac7f)
e6b739a: IDEA-117059 (same temp. directory for updater)
2679834: introduced idea.register.bundled.fonts registry to be able to switch off bundled fonts registration in order to avoid garbled text in editor (IDEA-93404) [r=Konstantin.Bulenkov] (cherry picked from commit e2cdb6d)
16eb783: fix null project
05de913: report missing optimizedFileManager only once
1b747fe: correct place for optimizedFileManager.jar
4713bfc: Merge branch '133' of git.labs.intellij.net:idea/community into 133
c2c0281: Jediterm updated.
26cf0f4: Mouse selection should always work in Terminal (IDEA-117210).
1f68d01: reconfigure navbar toolbar actions
1ae092c: show separators in navbar toolbar
afcfe95: Setup composite as it is done in EditorImpl.paintComponent.
66f161d: Behave the same as EditorImpl.
013c138: Use Source Code Pro as we don't have problems with unprintable pseudo-graphics as we iterate fonts to find suitable one for unprintable characters.
9796737: special icon for generated test root [rev by Peter]
2398eb9: make adapt_builder_() overridable (initState -> public)
2ef1c62: [git] Quick-fix for IDEA-115581: don't fail, just skip such hashes
1578562: [vcs] IDEA-109608 Apply patch: Fix path detection for new files + test
080813c: update Source Code Pro to version 17
f9c2953: IDEA-117211 empty elements in Search Everywhere
32ebdf3: error reporting in 'Project Structure' dialog: merge UI updates (IDEA-116808, IDEA-110799) [rev by Maxim M.]
2bab20f: added quick-fix to delete all unused libraries (IDEA-99885) [rev by Maxim M.]
f069657: disable GroovyShell because it doesn't work on win {^Peter]
637a5ba: Merge branch '133' of git.labs.intellij.net:idea/community into 133
dd8e18a: moved to core-impl
47f94f0: IDEA-104734 Dracula: Cannot see well active tab in Modules Settings
e2c1637: removed LOG.error for null syntax highlighter (cherry picked from commit 3e4c22c) [r=Peter.Gromov]
d4240b2: check that index for which indexUnsavedDocument is performed can be applied to given file type (EA-47740) [r=Eugene.Zhuravlev] (cherry picked from commit 0057f81)
acede1f: Merge branch '133' of git.labs.intellij.net:idea/community into 133
5ffb206: PsiSearchHelper changes cherry-picked (r:Peter)
1669188: avoid blocking runReadAction in debug logging
ba70dd4: Minor typo fix (IDEA-116432 Incorrect Spelling of Eclipse) (cherry picked from commit 3c553d6)
aadedc9: IDEA-117192 NavBar popup shows in wrong place when navigating to the directory from popup
c3b6615: Merge remote-tracking branch 'origin/133' into 133
a915da31: Merge remote-tracking branch 'origin/133' into 133
9a90c16: IDEA-116866 (path overriding for plugins/log dirs fixed once again)
bc3d847: Merge remote-tracking branch 'origin/133' into 133
6081b4f: removed signing for CE launchers.
21cd0c7: tuned UI for got it button
f986c7c: method refs: do not choose more specific method between methods with different number of params
aa7db43: IDEA-116756 Gradle multi-module project with deep-nested modules - idea places iml file in the wrong directory (cherry picked from commit 8e2ad06)
3bd2a55: plugin advertiser: ensure that older plugins won't be ever suggested
f739564: plugins advertise: download plugin if it was not explicitly disabled (IDEA-117003)
df398a9: plugins advertiser: provide loading plugin version for renderer
751d401: CCE (IDEA-117119)
03b253b: lambda: do not distinguish between ellipsis and arrays for formal lambda params checks (IDEA-117124)
ca191c9: index property optimization [^Peter]
4f7ba3a: class searching optimization [^Peter]
4e7ff49: IDEA-116628 No nulls in type parameters [^Peter]
a30f59b: typo [^Peter]
580cb5e: Merge branch '133' of git.labs.intellij.net:idea/community into 133
9c2489a: Take default shell from env variable.
9b2b7f3: File chooser for shell path (PY-11334).
9758753: Take shell path setting before every process creation.
3dbe4eb: use the same background color
8b8c0df: set lower limit of 1 for max_worker_threads_count (for low-profile cpu)
2a67fed: test for unzipping malformed zip archive (cherry picked from commit cd35a94) CR-WS-267
2c74d46: target error message for a newly created project (cherry picked from commit 8e10c3a) CR-WS-267
41311ea: use ZipFile, because it throws exception for a malformed zip archive (cherry picked from commit 02da50f) CR-WS-267
323523c: make IntelliJ laf by default on Linux
9d74b04: update artwork for version 13
d7ce47d: add history
42733a8: utility class holding two colors for gradient painting
537dd04: better colors? fix balloon and popup borders
787ec72: added signing for community launchers in zip distr.
f577493: use backported V8 CHM only for Oracle or Apple JDK (IDEA-116404 Java code compilation does not work with IBM JDK)
ae19efc: isEap = false, no error reporting
7e1f100: ~update mockJDK-1.7 used classes to be at least from jdk 1.5
c812622: do not create raw outer types during diamond inference
d0bc4ad: Merge branch '133' of git.labs.intellij.net:idea/community into 133
b6fe06f: FinderRecursivePanel: do not perform getListItems() in EDT on update (cherry picked from commit a128fa5) CR-IC-3413
e189085: IDEA-116866 (path overriding for plugins/log dirs fixed)
c50b1f1: Cleanup (punctuation)
cf75962: External System: support for multiple tasks execution added (cherry picked from commit a6f9141)
60418e9: IDEA-100294 Cannot edit a file - text jumps all over the screen (cherry picked from commit 36bacc0) [cdr]
3da28ad: Merge remote-tracking branch 'origin/133' into 133
86b3924: mock 1.8 jdk
ae8c2b0: switching to java.util.ConcurrentHashMap in jps code; eliminate unneeded map queries
f3d2761: EA-52322 (diagnostic)
f0d71c1: copyright: fix for 2 open projects
e797eb4: javadoc: keep whitespaces in {@code} tags (IDEA-109997) (cherry picked from commit d08af6dfed35217f3bb03093e8c549ec3065d258)
aa52879: IDEA-117082 Anonymous class assigned to final field (cherry picked from commit 02cabc4e849835259d9d837f86493c5e4ff7269c)
c040d2f: junit: do not reuse directory configuration from another test root (IDEA-116871) (cherry picked from commit 354fece7efab569fa05b135ab912bee758a6d3f7)
99043c6: junit: do not create directory configuration when selection is not under test root, e.g. module content root (IDEA-116871) (cherry picked from commit effc865ab3bff89d4651054569ef7ac4f86d7b33)
f8ff71b: product name -> full product name (IDEA-117070) (cherry picked from commit 2b4dc107514b4bd13ec4dced1144c81de79a0bb7)
d60166d: plugins advertiser: ensure that all installed plugins would be enabled - check also unknown plugins (IDEA-117068) (cherry picked from commit 99ffd837ba1ec2523ae8c4faa2060c84b5941986)
b3ed3c2: plugins advertiser: do not suggest to update to ultimate on implicitly disabled plugins (IDEA-117040) (cherry picked from commit e5452974f1a45693dd8ddb967525d37cd54f3ba4)
61ebb02: IDEA-116991 "IDE is up to date" message (cherry picked from commit 094ac76636050b6f0796c9802342cb3d431eeab0)
a4dc3a5: lambda: process lambda as parameter for anonymous class (IDEA-116987) (cherry picked from commit bf64625fb2e79f29f924d47fb68ec55d7c46d954)
7be1ec1: IDEA-117071 (language level in decompiled .class files)
5e5d914: relative path - special url, encoding is not required (cherry picked from commit 58704c7)
7f786c5: cleanup (cherry picked from commit 3868464)
208311d: cleanup (cherry picked from commit d58146c)
53f1175: CR-IC-3246 (cherry picked from commit 5d6a0c8)
a186992: CR-IC-3246 (cherry picked from commit 51864f4)
04cd96d: open in browser — choose url, show full url, not only path (decoded form with parameters) (cherry picked from commit b3fff55)
bb59091: WeightBasedComparator — string natural compare (cherry picked from commit 86971b9)
52c78b1: overrides (cherry picked from commit 716766a)
5b53293: Urls.newFromIdea returns not-null (cherry picked from commit f47f98a)
fde95ae: move Url to platform - avoid raw string (cherry picked from commit d4e4a40)
7dabf92: UriUtil.trimLastSlash refine Url nullability (newFromIdea is not yet done) (cherry picked from commit 9b8aac5)
e1bcebb: CR-IC-2986 (cherry picked from commit 34ef731)
6a65720: cleanup (cherry picked from commit e50df4c)
60e168b: CR-IC-2986 MessageBuilder -> MessageDialogBuilder (cherry picked from commit 1999b51)
be3b2ec: some memory tune-ups
cfbafa0: IDEA-117077 Can't remove files from Recent Files
3f42891: EA-52338 - assert: ComponentManagerImpl.getComponent (cherry picked from commit 7c076b6)
58bc683: IDEA-117030 Groovy/Gradle frequent, severe hangs (cherry picked from commit aadeb26)
0ef7db2: IDEA-117073 Recent files and Switcher are not centred in ide window
4a2dde3: file watchers tips should be in WS only
39ee2d2: update complete statement tips
292b280: remove image tag
bffe81e: missed images
b975e7d: Add missing module definition.
3cd9608: Add license for "aether-api-0.9.0.M2.jar" (cherry picked from commit 0df2a18)
d63a566: IDEA-116452 "Resolve workspace artifacts" option doesn't work with Maven 3.1.x (cherry picked from commit 8c35e68)
9103476: Enter in SE should close popup if selection is a setting
4f37f20: button placed on top, should be in the middle
6c28556: [log] IDEA-116399 Fix filter by branch
7684e66: IDEA-116881 Please time stamp gradle tasks (cherry picked from commit 79c4e6e)
db139a1: IDEA-116891 gradle import creates a lot of extra empty directories (cherry picked from commit 9732da7)
9ed8e39: WEB-9933 What should happen when creating node.js Express App as New Module? (cherry picked from commit a0c7d51) CR-WS-262
2e2fd29: IDEA-116891 gradle import creates a lot of extra empty directories (cherry picked from commit ca7e083)
5902fb8: IDEA-116974 Gradle Plugin doesn't handle 'providedCompile' dependencies in 'war' projects correctly (cherry picked from commit d3f9d06)
0e97c89: Merge remote-tracking branch 'origin/133' into 133
5be1c50: IDEA-115546 Full Screen Mode: main menu persists on screen, when invoked by the keyboard shortcut(reviewed by kb)
4055528: IDEA-111161 Flat tool window design PATCH(reviewed by kb)
17913b8: Lens pixel hunting (reviewed by kb)
38dd8e8: select correct shell runner in title [^Peter]
57befaf: IDEA-116917 check for jansi in classpath [^Peter]
93e3010: IDEA-66494 Switching between search and replace (cherry picked from commit d7dc6ca) [r=Peter.Gromov]
45d852b: IDEA-66494 Switching between search and replace (cherry picked from commit d7dc6ca) [r=Peter.Gromov]
7673aeb: IDEA-116952 IntelliJ LAF issue (set label.disabledForeground to 999999)
56d2cb6: IDEA-116911 Speed search: wrong background in recent files
6ecd960: IDEA-115577 Commit Changes: keyboard shortcut for Commit Message History does not work
27aa855: IDEA-115708 Add workaround by setting global SSLContext (cherry picked from commit fc3f452bbbef193a3ebf6fd28d7e0bffb14a9a5a)
7c3e066: get rid of invoke later [^Peter]
3f10d5b: special icon for 'generated source' roots: added file forgotten by first cherry-pick (cherry picked from commit 35806f22)
6f3780e: grayed text is invisible on Linux
f64ba46: menu is not visible on Linux + IntelliJ theme
e7f0816: [vcs] IDEA-115571 Don't clean change lists's commit message until committed
f0226f9: [log] Make "show details" & "show long edges" actions dumb aware (cherry picked from commit 726ffc1)
8ca08ac: [log] IDEA-116950 Draw just "tag +" instead of "tag + 5 more" (cherry picked from commit 49a033a)
976a8ef: [log] IDEA-116950 Don't display all tags if there are too many of them
4a1db8f: [log] Refactor: move ref painter & drawRefs & calc refs padding to the common parent class (cherry picked from commit 3bb3524)
5dd3597: IDEA-113730 Implemented "cat" command to read content as binary data (not to read as text data and then convert to bytes using some encoding) (cherry picked from commit efd5985)
4201c87: update tips
5c4c6e0: special icon for 'generated source' roots [rev by Peter] (cherry picked from commit 35806f2)
fcc237f: [^nicity] fix outdated javadoc (completion is performed in a read action) (cherry picked from commit d4e5553)
0f918a9: [^nicity] support hippie completion at the file start (EA-52100) (cherry picked from commit 3334c0b)
41b5038: IDEA-102449 Mac OS + JDK 1.7: dialog sheets go to background if focus is moved from IDEA and then back
aff52ee: IDEA-116784 Error Parsing Regex /\s/ in Groovy [^Peter]
8bf0c61: IDEA-95170 closure parameter type [^peter]
8f7c63d: IDEA-116378 only expressions are available in loop conditions [^peter]
d889262: IDEA-116837 Groovy: don't suggest to shorten references in comments [^peter]
f835a08: IDEA-116621 Groovy: Extract Parameter Refactoring: 'Replace this occurrence only' replaces all occurrences in current method [^peter]
6ee4359: [log] fix action's update()
5b8fb93: do not update recent projects on closing in headless mode
3fb3322: Merge remote-tracking branch 'origin/133' into 133
9251d90: SSH console - credentials validation (cherry picked from commit 8b7b23a)
9947162: IDEA-116824 Gradle: Provide an inspection & quickfix for multiple custom maven repo links (cherry picked from commit 810199f)
Change-Id: I47b8e5f8b6b865ec46d5625dd1838900539d7d93
Diffstat (limited to 'java')
184 files changed, 2771 insertions, 676 deletions
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index b67a815abc9c..0f13731ca723 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -924,8 +924,6 @@ public class BuildManager implements ApplicationComponent{ launcherCp.add(ClasspathBootstrap.getResourcePath(launcherClass)); launcherCp.add(compilerPath); ClasspathBootstrap.appendJavaCompilerClasspath(launcherCp); - // this will disable standard extensions to ensure javac is loaded from the right tools.jar - cmdLine.addParameter("-Djava.ext.dirs="); cmdLine.addParameter("-classpath"); cmdLine.addParameter(classpathToString(launcherCp)); diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java index 135b15488165..e0a7ffa0d37c 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java @@ -41,7 +41,7 @@ class BuildMessageDispatcher extends SimpleChannelInboundHandler<CmdlineRemotePr private static final AttributeKey<SessionData> SESSION_DATA = new AttributeKey<SessionData>("BuildMessageDispatcher.sessionData"); - private final Map<UUID, SessionData> myMessageHandlers = new ConcurrentHashMap<UUID, SessionData>(); + private final Map<UUID, SessionData> myMessageHandlers = new ConcurrentHashMap<UUID, SessionData>(16, 0.75f, 1); private final Set<UUID> myCanceledSessions = new ConcurrentHashSet<UUID>(); public void registerBuildMessageHandler(UUID sessionId, diff --git a/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java b/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java index 3cb12602c149..ef9d84befed0 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java @@ -15,19 +15,18 @@ */ package com.intellij.compiler.server; -import com.intellij.compiler.make.CachingSearcher; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Ref; -import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.search.*; -import com.intellij.psi.util.PsiUtil; +import com.intellij.util.SmartList; import com.intellij.util.cls.ClsUtil; import com.intellij.util.concurrency.SequentialTaskExecutor; import io.netty.channel.Channel; @@ -45,15 +44,11 @@ import java.util.*; */ public abstract class DefaultMessageHandler implements BuilderMessageHandler { private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.server.DefaultMessageHandler"); - private final int MAX_CONSTANT_SEARCHES = Registry.intValue("compiler.max.static.constants.searches"); private final Project myProject; - private int myConstantSearchesCount = 0; - private final CachingSearcher mySearcher; private final SequentialTaskExecutor myTaskExecutor = new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE); protected DefaultMessageHandler(Project project) { myProject = project; - mySearcher = new CachingSearcher(project); } @Override @@ -62,6 +57,7 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler { @Override public final void handleBuildMessage(final Channel channel, final UUID sessionId, final CmdlineRemoteProto.Message.BuilderMessage msg) { + //noinspection EnumSwitchStatementWhichMissesCases switch (msg.getType()) { case BUILD_EVENT: handleBuildEvent(sessionId, msg.getBuildEvent()); @@ -100,16 +96,20 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler { LOG.debug("Constant search task: cannot search in dumb mode"); } else { - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - try { - String qualifiedName = ownerClassName.replace('$', '.'); - final PsiClass[] classes = JavaPsiFacade.getInstance(myProject).findClasses(qualifiedName, GlobalSearchScope.allScope(myProject)); - if (isRemoved) { + final String qualifiedName = ownerClassName.replace('$', '.'); + final PsiClass[] classes = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass[]>() { + public PsiClass[] compute() { + return JavaPsiFacade.getInstance(myProject).findClasses(qualifiedName, GlobalSearchScope.allScope(myProject)); + } + }); + + try { + if (isRemoved) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { if (classes.length > 0) { for (PsiClass aClass : classes) { - final boolean success = performRemovedConstantSearch(aClass, fieldName, accessFlags, affectedPaths); + final boolean success = aClass.isValid() && performRemovedConstantSearch(aClass, fieldName, accessFlags, affectedPaths); if (!success) { isSuccess.set(Boolean.FALSE); break; @@ -122,44 +122,49 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler { ); } } - else { - if (classes.length > 0) { - boolean foundAtLeastOne = false; + }); + } + else { + if (classes.length > 0) { + final Collection<PsiField> changedFields = ApplicationManager.getApplication().runReadAction(new Computable<Collection<PsiField>>() { + public Collection<PsiField> compute() { + final List<PsiField> fields = new SmartList<PsiField>(); for (PsiClass aClass : classes) { - PsiField changedField = null; - for (PsiField psiField : aClass.getFields()) { - if (fieldName.equals(psiField.getName())) { - changedField = psiField; - break; - } + if (!aClass.isValid()) { + return Collections.emptyList(); } - if (changedField == null) { - continue; - } - foundAtLeastOne = true; - final boolean success = performChangedConstantSearch(aClass, changedField, accessFlags, accessChanged, affectedPaths); - if (!success) { - isSuccess.set(Boolean.FALSE); - break; + final PsiField changedField = aClass.findFieldByName(fieldName, false); + if (changedField != null) { + fields.add(changedField); } } - if (!foundAtLeastOne) { - isSuccess.set(Boolean.FALSE); - LOG.debug("Constant search task: field " + fieldName + " not found in classes " + qualifiedName); - } + return fields; } - else { - isSuccess.set(Boolean.FALSE); - LOG.debug("Constant search task: class " + qualifiedName + " not found"); + }); + if (changedFields.isEmpty()) { + isSuccess.set(Boolean.FALSE); + LOG.debug("Constant search task: field " + fieldName + " not found in classes " + qualifiedName); + } + else { + for (final PsiField changedField : changedFields) { + if (!accessChanged && ClsUtil.isPrivate(accessFlags)) { + // optimization: don't need to search, cause may be used only in this class + continue; + } + affectDirectUsages(changedField, accessFlags, accessChanged, affectedPaths); } } } - catch (Throwable e) { + else { isSuccess.set(Boolean.FALSE); - LOG.debug("Constant search task: failed with message " + e.getMessage()); + LOG.debug("Constant search task: class " + qualifiedName + " not found"); } } - }); + } + catch (Throwable e) { + isSuccess.set(Boolean.FALSE); + LOG.debug("Constant search task: failed with message " + e.getMessage()); + } } } finally { @@ -188,6 +193,7 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler { // wait some time for (int idx = 0; idx < 5; idx++) { try { + //noinspection BusyWait Thread.sleep(10L); } catch (InterruptedException ignored) { @@ -201,52 +207,13 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler { return isDumb; } - private boolean performChangedConstantSearch(PsiClass aClass, PsiField field, int accessFlags, boolean isAccessibilityChange, Set<String> affectedPaths) { - if (!isAccessibilityChange && ClsUtil.isPrivate(accessFlags)) { - return true; // optimization: don't need to search, cause may be used only in this class - } - final Set<PsiElement> usages = new HashSet<PsiElement>(); - try { - addUsages(field, usages, isAccessibilityChange); - for (final PsiElement usage : usages) { - affect(usage, affectedPaths); - //final PsiClass ownerClass = getOwnerClass(usage); - //if (ownerClass != null && !ownerClass.equals(aClass)) { - // affect(ownerClass, affectedPaths); - //} - //else if (ownerClass == null) { - // affect(usage, affectedPaths); - //} - } - } - catch (PsiInvalidElementAccessException ignored) { - LOG.debug("Constant search task: PIEAE thrown while searching of usages of changed constant"); - return false; - } - catch (ProcessCanceledException ignored) { - LOG.debug("Constant search task: PCE thrown while searching of usages of changed constant"); - return false; - } - return true; - } - - private boolean performRemovedConstantSearch(@Nullable final PsiClass aClass, String fieldName, int accessFlags, final Set<String> affectedPaths) { - SearchScope searchScope = GlobalSearchScope.projectScope(myProject); - if (aClass != null && ClsUtil.isPackageLocal(accessFlags)) { - final PsiFile containingFile = aClass.getContainingFile(); - if (containingFile instanceof PsiJavaFile) { - final String packageName = ((PsiJavaFile)containingFile).getPackageName(); - final PsiPackage aPackage = JavaPsiFacade.getInstance(myProject).findPackage(packageName); - if (aPackage != null) { - searchScope = PackageScope.packageScope(aPackage, false); - searchScope = searchScope.intersectWith(aClass.getUseScope()); - } - } - } + private boolean performRemovedConstantSearch(@Nullable final PsiClass aClass, String fieldName, int fieldAccessFlags, final Set<String> affectedPaths) { final PsiSearchHelper psiSearchHelper = PsiSearchHelper.SERVICE.getInstance(myProject); final Ref<Boolean> result = new Ref<Boolean>(Boolean.TRUE); + final PsiFile fieldContainingFile = aClass != null? aClass.getContainingFile() : null; + processIdentifiers(psiSearchHelper, new PsiElementProcessor<PsiIdentifier>() { @Override public boolean execute(@NotNull PsiIdentifier identifier) { @@ -254,9 +221,13 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler { final PsiElement parent = identifier.getParent(); if (parent instanceof PsiReferenceExpression) { final PsiClass ownerClass = getOwnerClass(parent); - if (ownerClass != null /*&& !ownerClass.equals(aClass)*/) { - if (ownerClass.getQualifiedName() != null) { - affect(ownerClass, affectedPaths); + if (ownerClass != null && ownerClass.getQualifiedName() != null) { + final PsiFile usageFile = ownerClass.getContainingFile(); + if (usageFile != null && !usageFile.equals(fieldContainingFile)) { + final VirtualFile vFile = usageFile.getOriginalFile().getVirtualFile(); + if (vFile != null) { + affectedPaths.add(vFile.getPath()); + } } } } @@ -268,19 +239,25 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler { return false; } } - }, fieldName, searchScope, UsageSearchContext.IN_CODE); + }, fieldName, getSearchScope(aClass, fieldAccessFlags), UsageSearchContext.IN_CODE); return result.get(); } - private static void affect(PsiElement ownerClass, Set<String> affectedPaths) { - final PsiFile containingPsi = ownerClass.getContainingFile(); - if (containingPsi != null) { - final VirtualFile vFile = containingPsi.getOriginalFile().getVirtualFile(); - if (vFile != null) { - affectedPaths.add(vFile.getPath()); + private SearchScope getSearchScope(PsiClass aClass, int fieldAccessFlags) { + SearchScope searchScope = GlobalSearchScope.projectScope(myProject); + if (aClass != null && ClsUtil.isPackageLocal(fieldAccessFlags)) { + final PsiFile containingFile = aClass.getContainingFile(); + if (containingFile instanceof PsiJavaFile) { + final String packageName = ((PsiJavaFile)containingFile).getPackageName(); + final PsiPackage aPackage = JavaPsiFacade.getInstance(myProject).findPackage(packageName); + if (aPackage != null) { + searchScope = PackageScope.packageScope(aPackage, false); + searchScope = searchScope.intersectWith(aClass.getUseScope()); + } } } + return searchScope; } private static boolean processIdentifiers(PsiSearchHelper helper, @NotNull final PsiElementProcessor<PsiIdentifier> processor, @NotNull final String identifier, @NotNull SearchScope searchScope, short searchContext) { @@ -290,35 +267,59 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler { return !(element instanceof PsiIdentifier) || processor.execute((PsiIdentifier)element); } }; - return helper.processElementsWithWord(processor1, searchScope, identifier, searchContext, true); + return helper.processElementsWithWord(processor1, searchScope, identifier, searchContext, true, false); } - private void addUsages(PsiField psiField, Collection<PsiElement> usages, final boolean ignoreAccessScope) throws ProcessCanceledException { - final int count = myConstantSearchesCount; - if (count > MAX_CONSTANT_SEARCHES) { - throw new ProcessCanceledException(); - } - Collection<PsiReference> references = mySearcher.findReferences(psiField, ignoreAccessScope)/*doFindReferences(searchHelper, psiField)*/; + private void affectDirectUsages(final PsiField psiField, final int fieldAccessFlags, final boolean ignoreAccessScope, final Set<String> affectedPaths) throws ProcessCanceledException { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + if (psiField.isValid()) { + final PsiFile fieldContainingFile = psiField.getContainingFile(); + final Set<PsiFile> processedFiles = new HashSet<PsiFile>(); + if (fieldContainingFile != null) { + processedFiles.add(fieldContainingFile); + } + // if field is invalid, the file might be changed, so next time it is compiled, + // the constant value change, if any, will be processed + final Collection<PsiReferenceExpression> references = doFindReferences(psiField, fieldAccessFlags, ignoreAccessScope); + for (final PsiReferenceExpression ref : references) { + final PsiElement usage = ref.getElement(); + final PsiFile containingPsi = usage.getContainingFile(); + if (containingPsi != null && processedFiles.add(containingPsi)) { + final VirtualFile vFile = containingPsi.getOriginalFile().getVirtualFile(); + if (vFile != null) { + affectedPaths.add(vFile.getPath()); + } + } + } + } + } + }); + } - myConstantSearchesCount++; + private Collection<PsiReferenceExpression> doFindReferences(final PsiField psiField, int fieldAccessFlags, boolean ignoreAccessScope) { + final SmartList<PsiReferenceExpression> result = new SmartList<PsiReferenceExpression>(); - for (final PsiReference ref : references) { - if (!(ref instanceof PsiReferenceExpression)) { - continue; - } - PsiElement e = ref.getElement(); - usages.add(e); - PsiField ownerField = getOwnerField(e); - if (ownerField != null) { - if (ownerField.hasModifierProperty(PsiModifier.FINAL)) { - PsiExpression initializer = ownerField.getInitializer(); - if (initializer != null && PsiUtil.isConstantExpression(initializer)) { - // if the field depends on the compile-time-constant expression and is itself final - addUsages(ownerField, usages, ignoreAccessScope); + final SearchScope searchScope = ignoreAccessScope? GlobalSearchScope.projectScope(myProject) : getSearchScope(psiField.getContainingClass(), fieldAccessFlags); + + processIdentifiers(PsiSearchHelper.SERVICE.getInstance(myProject), new PsiElementProcessor<PsiIdentifier>() { + @Override + public boolean execute(@NotNull PsiIdentifier identifier) { + final PsiElement parent = identifier.getParent(); + if (parent instanceof PsiReferenceExpression) { + final PsiReferenceExpression refExpression = (PsiReferenceExpression)parent; + if (refExpression.isReferenceTo(psiField)) { + synchronized (result) { + // processor's code may be invoked from multiple threads + result.add(refExpression); + } } } + return true; } - } + }, psiField.getName(), searchScope, UsageSearchContext.IN_CODE); + + return result; } @Nullable @@ -340,18 +341,4 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler { return null; } - @Nullable - private static PsiField getOwnerField(PsiElement element) { - while (!(element instanceof PsiFile)) { - if (element instanceof PsiClass) { - break; - } - if (element instanceof PsiField) { // top-level class - return (PsiField)element; - } - element = element.getParent(); - } - return null; - } - } diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/SetValueAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/SetValueAction.java index 04f9dcb991bd..8adff3f3a6ff 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/SetValueAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/SetValueAction.java @@ -481,8 +481,10 @@ public class SetValueAction extends DebuggerAction { stateManager.addListener(new DebuggerContextListener() { public void changeEvent(DebuggerContextImpl newContext, int event) { - stateManager.removeListener(this); - editor.cancelEditing(); + if (event != DebuggerSession.EVENT_THREADS_REFRESH) { + stateManager.removeListener(this); + editor.cancelEditing(); + } } }); diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java index 54d1545f74f6..39a397755a5e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java @@ -19,8 +19,11 @@ import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.DebuggerManagerEx; import com.intellij.debugger.InstanceFilter; import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.debugger.engine.DebuggerUtils; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; import com.intellij.debugger.engine.requests.RequestManagerImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.impl.DebuggerSession; import com.intellij.debugger.ui.breakpoints.Breakpoint; import com.intellij.debugger.ui.breakpoints.BreakpointManager; @@ -29,12 +32,14 @@ import com.intellij.debugger.ui.impl.watch.DebuggerTree; import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; import com.intellij.debugger.ui.impl.watch.FieldDescriptorImpl; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; @@ -83,7 +88,10 @@ public class ToggleFieldBreakpointAction extends AnAction { RequestManagerImpl.createRequests(fieldBreakpoint); - manager.editBreakpoint(fieldBreakpoint, CommonDataKeys.EDITOR.getData(e.getDataContext())); + final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext()); + if (editor != null) { + manager.editBreakpoint(fieldBreakpoint, editor); + } } } else { @@ -126,7 +134,7 @@ public class ToggleFieldBreakpointAction extends AnAction { @Nullable public static SourcePosition getPlace(AnActionEvent event) { final DataContext dataContext = event.getDataContext(); - Project project = event.getData(CommonDataKeys.PROJECT); + final Project project = event.getData(CommonDataKeys.PROJECT); if(project == null) { return null; } @@ -142,8 +150,28 @@ public class ToggleFieldBreakpointAction extends AnAction { final DebuggerTreeNodeImpl selectedNode = DebuggerAction.getSelectedNode(dataContext); if(selectedNode != null && selectedNode.getDescriptor() instanceof FieldDescriptorImpl) { - FieldDescriptorImpl descriptor = (FieldDescriptorImpl)selectedNode.getDescriptor(); - return descriptor.getSourcePosition(project, DebuggerAction.getDebuggerContext(dataContext)); + final DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(dataContext); + final DebugProcessImpl debugProcess = debuggerContext.getDebugProcess(); + if (debugProcess != null) { // if there is an active debugsession + final Ref<SourcePosition> positionRef = new Ref<SourcePosition>(null); + debugProcess.getManagerThread().invokeAndWait(new DebuggerContextCommandImpl(debuggerContext) { + public Priority getPriority() { + return Priority.HIGH; + } + public void threadAction() { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final FieldDescriptorImpl descriptor = (FieldDescriptorImpl)selectedNode.getDescriptor(); + positionRef.set(descriptor.getSourcePosition(project, debuggerContext)); + } + }); + } + }); + final SourcePosition sourcePosition = positionRef.get(); + if (sourcePosition != null) { + return sourcePosition; + } + } } if(DebuggerAction.isContextView(event)) { diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java index 9c4ec5d39bca..d539de50c150 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java @@ -19,14 +19,10 @@ import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.EditorFactory; -import com.intellij.openapi.editor.ex.EditorEx; -import com.intellij.openapi.editor.impl.DocumentImpl; -import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.ui.EditorTextField; +import com.intellij.xdebugger.impl.ui.TextViewer; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -55,7 +51,7 @@ public class ViewTextAction extends BaseValueAction { setCancelButtonText("Close"); setCrossClosesWindow(true); - myTextViewer = new TextViewer(project); + myTextViewer = new TextViewer(project, true, true); init(); } @@ -78,33 +74,5 @@ public class ViewTextAction extends BaseValueAction { panel.setPreferredSize(new Dimension(300, 200)); return panel; } - } - - - private static class TextViewer extends EditorTextField { - - private TextViewer(Project project) { - super(createDocument(), project, FileTypes.PLAIN_TEXT, true, false); - } - - private static Document createDocument() { - final Document document = EditorFactory.getInstance().createDocument(""); - if (document instanceof DocumentImpl) { - ((DocumentImpl)document).setAcceptSlashR(true); - } - return document; - } - - protected EditorEx createEditor() { - final EditorEx editor = super.createEditor(); - editor.setHorizontalScrollbarVisible(true); - editor.setVerticalScrollbarVisible(true); - editor.setEmbeddedIntoDialogWrapper(true); - editor.getComponent().setPreferredSize(null); - editor.getSettings().setUseSoftWraps(true); - return editor; - } - } - } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java index 58f4c7b70bc4..f9c7b84fdfa0 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java @@ -22,6 +22,7 @@ import com.intellij.debugger.engine.events.DebuggerCommandImpl; import com.intellij.debugger.engine.events.SuspendContextCommandImpl; import com.intellij.debugger.engine.requests.LocatableEventRequestor; import com.intellij.debugger.engine.requests.MethodReturnValueWatcher; +import com.intellij.debugger.impl.DebuggerSession; import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; import com.intellij.debugger.jdi.VirtualMachineProxyImpl; import com.intellij.debugger.requests.Requestor; @@ -39,7 +40,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.registry.Registry; import com.intellij.xdebugger.impl.XDebugSessionImpl; import com.sun.jdi.InternalException; import com.sun.jdi.ThreadReference; @@ -182,7 +182,7 @@ public class DebugProcessEvents extends DebugProcessImpl { getManagerThread().invokeAndWait(new DebuggerCommandImpl() { protected void action() throws Exception { - if (eventSet.suspendPolicy() == EventRequest.SUSPEND_ALL && !enableBreakpointsDuringEvaluation()) { + if (eventSet.suspendPolicy() == EventRequest.SUSPEND_ALL && !DebuggerSession.enableBreakpointsDuringEvaluation()) { // check if there is already one request with policy SUSPEND_ALL for (SuspendContextImpl context : getSuspendManager().getEventContexts()) { if (context.getSuspendPolicy() == EventRequest.SUSPEND_ALL) { @@ -420,7 +420,7 @@ public class DebugProcessEvents extends DebugProcessImpl { final SuspendManager suspendManager = getSuspendManager(); SuspendContextImpl evaluatingContext = SuspendManagerUtil.getEvaluatingContext(suspendManager, getSuspendContext().getThread()); - if (evaluatingContext != null && !enableBreakpointsDuringEvaluation()) { + if (evaluatingContext != null && !DebuggerSession.enableBreakpointsDuringEvaluation()) { // is inside evaluation, so ignore any breakpoints suspendManager.voteResume(suspendContext); return; @@ -476,10 +476,6 @@ public class DebugProcessEvents extends DebugProcessImpl { }); } - private static boolean enableBreakpointsDuringEvaluation() { - return Registry.is("debugger.enable.breakpoints.during.evaluation"); - } - private void processDefaultEvent(SuspendContextImpl suspendContext) { preprocessEvent(suspendContext, null); getSuspendManager().voteResume(suspendContext); diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java index dc9d1e9e1ec7..a5b1be2ba733 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java @@ -99,7 +99,7 @@ public abstract class DebugProcessImpl implements DebugProcess { private final Project myProject; private final RequestManagerImpl myRequestManager; - private VirtualMachineProxyImpl myVirtualMachineProxy = null; + private volatile VirtualMachineProxyImpl myVirtualMachineProxy = null; protected EventDispatcher<DebugProcessListener> myDebugProcessDispatcher = EventDispatcher.create(DebugProcessListener.class); protected EventDispatcher<EvaluationListener> myEvaluationDispatcher = EventDispatcher.create(EvaluationListener.class); @@ -685,11 +685,13 @@ public abstract class DebugProcessImpl implements DebugProcess { } public boolean canRedefineClasses() { - return myVirtualMachineProxy != null && myVirtualMachineProxy.canRedefineClasses(); + final VirtualMachineProxyImpl vm = myVirtualMachineProxy; + return vm != null && vm.canRedefineClasses(); } public boolean canWatchFieldModification() { - return myVirtualMachineProxy != null && myVirtualMachineProxy.canWatchFieldModification(); + final VirtualMachineProxyImpl vm = myVirtualMachineProxy; + return vm != null && vm.canWatchFieldModification(); } public boolean isInInitialState() { @@ -714,10 +716,11 @@ public abstract class DebugProcessImpl implements DebugProcess { public VirtualMachineProxyImpl getVirtualMachineProxy() { DebuggerManagerThreadImpl.assertIsManagerThread(); - if (myVirtualMachineProxy == null) { + final VirtualMachineProxyImpl vm = myVirtualMachineProxy; + if (vm == null) { throw new VMDisconnectedException(); } - return myVirtualMachineProxy; + return vm; } public void appendPositionManager(final PositionManager positionManager) { @@ -1820,7 +1823,8 @@ public abstract class DebugProcessImpl implements DebugProcess { } public boolean isPausePressed() { - return myVirtualMachineProxy != null && myVirtualMachineProxy.isPausePressed(); + final VirtualMachineProxyImpl vm = myVirtualMachineProxy; + return vm != null && vm.isPausePressed(); } public DebuggerCommandImpl createPauseCommand() { diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java index aa24a431dac8..19de95a585d3 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java @@ -21,6 +21,7 @@ import com.intellij.debugger.engine.*; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluationListener; import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.engine.jdi.StackFrameProxy; import com.intellij.debugger.engine.requests.RequestManagerImpl; import com.intellij.debugger.jdi.StackFrameProxyImpl; import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; @@ -43,9 +44,11 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.registry.Registry; import com.intellij.psi.PsiCompiledElement; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; @@ -284,7 +287,12 @@ public class DebuggerSession implements AbstractDebuggerSession { public void resume() { final SuspendContextImpl suspendContext = getSuspendContext(); if(suspendContext != null) { - mySteppingThroughThreads.clear(); + if (suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_ALL) { + mySteppingThroughThreads.clear(); + } + else { + mySteppingThroughThreads.remove(suspendContext.getThread()); + } resetIgnoreStepFiltersFlag(); resumeAction(myDebugProcess.createResumeCommand(suspendContext), EVENT_RESUME); } @@ -408,6 +416,15 @@ public class DebuggerSession implements AbstractDebuggerSession { LOG.debug("paused"); } + if (!shouldSetAsActiveContext(suspendContext)) { + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + getContextManager().fireStateChanged(getContextManager().getContext(), EVENT_THREADS_REFRESH); + } + }); + return; + } + ThreadReferenceProxyImpl currentThread = suspendContext.getThread(); final StackFrameContext positionContext; @@ -503,9 +520,10 @@ public class DebuggerSession implements AbstractDebuggerSession { else if (sourceMissing) { // adjust position to be position of the breakpoint in order to show the real originator of the event position = breakpointPosition; + final StackFrameProxy frameProxy = positionContext.getFrameProxy(); String className; try { - className = positionContext.getFrameProxy().location().declaringType().name(); + className = frameProxy != null? frameProxy.location().declaringType().name() : ""; } catch (EvaluateException e) { className = ""; @@ -527,6 +545,23 @@ public class DebuggerSession implements AbstractDebuggerSession { }); } + private boolean shouldSetAsActiveContext(final SuspendContextImpl suspendContext) { + final ThreadReferenceProxyImpl newThread = suspendContext.getThread(); + if (newThread == null || suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_ALL || isSteppingThrough(newThread)) { + return true; + } + final SuspendContextImpl currentSuspendContext = getContextManager().getContext().getSuspendContext(); + if (currentSuspendContext == null) { + return true; + } + if (enableBreakpointsDuringEvaluation()) { + final ThreadReferenceProxyImpl currentThread = currentSuspendContext.getThread(); + return currentThread == null || Comparing.equal(currentThread.getThreadReference(), newThread.getThreadReference()); + } + return false; + } + + public void resumed(final SuspendContextImpl suspendContext) { final SuspendContextImpl currentContext = getProcess().getSuspendManager().getPausedContext(); DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { @@ -626,4 +661,9 @@ public class DebuggerSession implements AbstractDebuggerSession { }); } } + + public static boolean enableBreakpointsDuringEvaluation() { + return Registry.is("debugger.enable.breakpoints.during.evaluation"); + } + } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java index 19607665ec51..a78cb1315ea7 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java @@ -31,7 +31,6 @@ import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.jdi.StackFrameProxyImpl; import com.intellij.icons.AllIcons; -import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; @@ -73,7 +72,7 @@ public class LineBreakpoint extends BreakpointWithHighlighter { private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.LineBreakpoint"); @Nullable - private OwnerMethod myOwnerMethod; + private String myOwnerMethodName; public static final @NonNls Key<LineBreakpoint> CATEGORY = BreakpointCategory.lookup("line_breakpoints"); protected LineBreakpoint(Project project) { @@ -138,7 +137,7 @@ public class LineBreakpoint extends BreakpointWithHighlighter { final RangeHighlighter highlighter = getHighlighter(); offset = highlighter != null? highlighter.getStartOffset() : -1; } - myOwnerMethod = findOwnerMethod(file, offset); + myOwnerMethodName = findOwnerMethod(file, offset); } @Override @@ -211,18 +210,6 @@ public class LineBreakpoint extends BreakpointWithHighlighter { } protected boolean acceptLocation(DebugProcessImpl debugProcess, ReferenceType classType, Location loc) { - final OwnerMethod owner = myOwnerMethod; - if (owner != null && owner.isJavaFile) { - // Additional filtering applicable to java files only. - // Consider: - // proc(()->{System.out.println("Task 1");}, ()->{System.out.println("Task 2");}); <breakpoint at this line> - // - // there will be 3 locations for this line: one corresponding to calling method, and two locations from - // the lambda expression implementation methods. - // Without additional filtering, breakpoint request will be set on each location, - // while we do not need to stop in lambda expressions here - return owner.matches(loc); - } return true; } @@ -438,16 +425,16 @@ public class LineBreakpoint extends BreakpointWithHighlighter { } @Nullable - private static OwnerMethod findOwnerMethod(final PsiFile file, final int offset) { + private static String findOwnerMethod(final PsiFile file, final int offset) { if (offset < 0 || file instanceof JspFile) { return null; } if (file instanceof PsiClassOwner) { - return ApplicationManager.getApplication().runReadAction(new Computable<OwnerMethod>() { + return ApplicationManager.getApplication().runReadAction(new Computable<String>() { @Override - public OwnerMethod compute() { + public String compute() { final PsiMethod method = DebuggerUtilsEx.findPsiMethod(file, offset); - return method != null? new OwnerMethod(method, file instanceof PsiJavaFile && JavaLanguage.INSTANCE.equals(file.getLanguage())) : null; + return method != null? method.getName() : null; } }); } @@ -577,28 +564,7 @@ public class LineBreakpoint extends BreakpointWithHighlighter { @Nullable public String getMethodName() { - final OwnerMethod owner = myOwnerMethod; - return owner != null? owner.name : null; + return myOwnerMethodName; } - private static final class OwnerMethod { - @NotNull - final String name; - final boolean isConstructor; - final boolean isJavaFile; - - OwnerMethod(@NotNull PsiMethod method, boolean isJavaFile) { - this(method.getName(), method.isConstructor(), isJavaFile); - } - - OwnerMethod(@NotNull String name, boolean isConstructor, boolean isJavaFile) { - this.name = name; - this.isConstructor = isConstructor; - this.isJavaFile = isJavaFile; - } - - boolean matches(Location loc) { - return isConstructor? loc.method().isConstructor() : name.equals(loc.method().name()); - } - } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java index 586dadfe5068..4b3f145995b2 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java @@ -25,7 +25,6 @@ import com.intellij.debugger.engine.JVMNameUtil; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; -import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.impl.DebuggerSession; import com.intellij.debugger.impl.PositionUtil; @@ -34,8 +33,6 @@ import com.intellij.debugger.ui.tree.FieldDescriptor; import com.intellij.debugger.ui.tree.NodeDescriptor; import com.intellij.debugger.ui.tree.render.ClassRenderer; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; @@ -104,40 +101,20 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes // trying to search, assuming declaring class is an anonymous class final DebugProcessImpl debugProcess = context.getDebugProcess(); if (debugProcess != null) { - final Computable<PsiClass> classComputable = new Computable<PsiClass>() { - public PsiClass compute() { - try { - final List<Location> locations = type.allLineLocations(); - if (!locations.isEmpty()) { - // important: use the last location to be sure the position will be within the anonymous class - final Location lastLocation = locations.get(locations.size() - 1); - final SourcePosition position = debugProcess.getPositionManager().getSourcePosition(lastLocation); - if (position != null) { - return JVMNameUtil.getClassAt(position); - } - } + try { + final List<Location> locations = type.allLineLocations(); + if (!locations.isEmpty()) { + // important: use the last location to be sure the position will be within the anonymous class + final Location lastLocation = locations.get(locations.size() - 1); + final SourcePosition position = debugProcess.getPositionManager().getSourcePosition(lastLocation); + if (position != null) { + aClass = JVMNameUtil.getClassAt(position); } - catch (AbsentInformationException ignored) { - } - catch (ClassNotPreparedException ignored) { - } - return null; } - }; - if (!DebuggerManagerThreadImpl.isManagerThread()) { - final Ref<PsiClass> classRef = new Ref<PsiClass>(null); - debugProcess.getManagerThread().invokeAndWait(new DebuggerContextCommandImpl(context) { - public Priority getPriority() { - return Priority.HIGH; - } - public void threadAction() { - classRef.set(classComputable.compute()); - } - }); - aClass = classRef.get(); } - else { - aClass = classComputable.compute(); + catch (AbsentInformationException ignored) { + } + catch (ClassNotPreparedException ignored) { } } } diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointType.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointType.java index c2088722880b..00b75499af9a 100644 --- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointType.java +++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointType.java @@ -2,11 +2,8 @@ package org.jetbrains.java.debugger.breakpoints; import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.engine.DebuggerUtils; -import com.intellij.facet.FacetManager; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.StdFileTypes; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; @@ -31,18 +28,8 @@ public class JavaBreakpointType extends XLineBreakpointTypeBase { @Override public boolean canPutAt(@NotNull final VirtualFile file, final int line, @NotNull Project project) { - if (SystemProperties.getBooleanProperty("java.debugger.xBreakpoint", false)) { - boolean result = doCanPutAt(PsiManager.getInstance(project).findFile(file)); - - // todo now applicable only if modules has facets, remove this check when java xbreakpoint will work - if (result && SystemProperties.getBooleanProperty("java.debugger.xBreakpoint.onlyIfHasFacets", false)) { - Module module = ModuleUtilCore.findModuleForFile(file, project); - return module != null && FacetManager.getInstance(module).getAllFacets().length > 0; - } - - return result; - } - return false; + return SystemProperties.getBooleanProperty("java.debugger.xBreakpoint", false) && + doCanPutAt(PsiManager.getInstance(project).findFile(file)); } @Override diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseLibrariesConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseLibrariesConfigurable.java index 0e522a821327..2552631ed48a 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseLibrariesConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseLibrariesConfigurable.java @@ -47,6 +47,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; import java.util.*; public abstract class BaseLibrariesConfigurable extends BaseStructureConfigurable { @@ -258,14 +259,23 @@ public abstract class BaseLibrariesConfigurable extends BaseStructureConfigurabl } public void removeLibrary(@NotNull LibraryProjectStructureElement element) { - getModelProvider().getModifiableModel().removeLibrary(element.getLibrary()); - myContext.getDaemonAnalyzer().removeElement(element); - final MyNode node = findNodeByObject(myRoot, element.getLibrary()); - if (node != null) { - removePaths(TreeUtil.getPathFromRoot(node)); + removeLibraries(Collections.singletonList(element)); + } + + public void removeLibraries(@NotNull List<LibraryProjectStructureElement> libraries) { + List<TreePath> pathsToRemove = new ArrayList<TreePath>(); + for (LibraryProjectStructureElement element : libraries) { + getModelProvider().getModifiableModel().removeLibrary(element.getLibrary()); + MyNode node = findNodeByObject(myRoot, element.getLibrary()); + if (node != null) { + pathsToRemove.add(TreeUtil.getPathFromRoot(node)); + } } + myContext.getDaemonAnalyzer().removeElements(libraries); + removePaths(pathsToRemove.toArray(new TreePath[pathsToRemove.size()])); } + @Override protected boolean removeLibrary(final Library library) { final LibraryTable table = library.getTable(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java index 930cb514a80a..1fc3dbd66162 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java @@ -41,6 +41,7 @@ import org.jetbrains.annotations.NotNull; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -148,7 +149,7 @@ public class LibraryProjectStructureElement extends ProjectStructureElement { @Override public ProjectStructureProblemDescription createUnusedElementWarning() { - final List<ConfigurationErrorQuickFix> fixes = Arrays.asList(new AddLibraryToDependenciesFix(), new RemoveLibraryFix()); + final List<ConfigurationErrorQuickFix> fixes = Arrays.asList(new AddLibraryToDependenciesFix(), new RemoveLibraryFix(), new RemoveAllUnusedLibrariesFix()); return new ProjectStructureProblemDescription("Library '" + StringUtil.escapeXml(myLibrary.getName()) + "'" + " is not used", null, createPlace(), ProjectStructureProblemType.unused("unused-library"), ProjectStructureProblemDescription.ProblemLevel.PROJECT, fixes, false); @@ -225,4 +226,24 @@ public class LibraryProjectStructureElement extends ProjectStructureElement { BaseLibrariesConfigurable.getInstance(myContext.getProject(), myLibrary.getTable().getTableLevel()).removeLibrary(LibraryProjectStructureElement.this); } } + + private class RemoveAllUnusedLibrariesFix extends ConfigurationErrorQuickFix { + private RemoveAllUnusedLibrariesFix() { + super("Remove All Unused Libraries"); + } + + @Override + public void performFix() { + BaseLibrariesConfigurable configurable = BaseLibrariesConfigurable.getInstance(myContext.getProject(), LibraryTablesRegistrar.PROJECT_LEVEL); + Library[] libraries = configurable.getModelProvider().getModifiableModel().getLibraries(); + List<LibraryProjectStructureElement> toRemove = new ArrayList<LibraryProjectStructureElement>(); + for (Library library : libraries) { + LibraryProjectStructureElement libraryElement = new LibraryProjectStructureElement(myContext, library); + if (myContext.getDaemonAnalyzer().getUsages(libraryElement).isEmpty()) { + toRemove.add(libraryElement); + } + } + configurable.removeLibraries(toRemove); + } + } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java index 91183b9b5655..97ed5b0da733 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java @@ -7,13 +7,13 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.MultiValuesMap; +import com.intellij.util.Alarm; import com.intellij.util.EventDispatcher; import com.intellij.util.ui.update.MergingUpdateQueue; import com.intellij.util.ui.update.Update; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; @@ -29,6 +29,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { private final Set<ProjectStructureElement> myElementsToShowWarningIfUnused = new HashSet<ProjectStructureElement>(); private final Map<ProjectStructureElement, ProjectStructureProblemDescription> myWarningsAboutUnused = new HashMap<ProjectStructureElement, ProjectStructureProblemDescription>(); private final MergingUpdateQueue myAnalyzerQueue; + private final MergingUpdateQueue myResultsUpdateQueue; private final EventDispatcher<ProjectStructureDaemonAnalyzerListener> myDispatcher = EventDispatcher.create(ProjectStructureDaemonAnalyzerListener.class); private final AtomicBoolean myStopped = new AtomicBoolean(false); private final ProjectConfigurationProblems myProjectConfigurationProblems; @@ -36,7 +37,9 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { public ProjectStructureDaemonAnalyzer(StructureConfigurableContext context) { Disposer.register(context, this); myProjectConfigurationProblems = new ProjectConfigurationProblems(this, context); - myAnalyzerQueue = new MergingUpdateQueue("Project Structure Daemon Analyzer", 300, false, null, this, null, false); + myAnalyzerQueue = new MergingUpdateQueue("Project Structure Daemon Analyzer", 300, false, null, this, null, Alarm.ThreadToUse.POOLED_THREAD); + myResultsUpdateQueue = new MergingUpdateQueue("Project Structure Analysis Results Updater", 300, false, MergingUpdateQueue.ANY_COMPONENT, + this, null, Alarm.ThreadToUse.SWING_THREAD); } private void doUpdate(final ProjectStructureElement element, final boolean check, final boolean collectUsages) { @@ -63,21 +66,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { ProjectStructureValidator.check(element, problemsHolder); } }.execute(); - invokeLater(new Runnable() { - @Override - public void run() { - if (myStopped.get()) return; - - if (LOG.isDebugEnabled()) { - LOG.debug("updating problems for " + element); - } - final ProjectStructureProblemDescription warning = myWarningsAboutUnused.get(element); - if (warning != null) - problemsHolder.registerProblem(warning); - myProblemHolders.put(element, problemsHolder); - myDispatcher.getMulticaster().problemsChanged(element); - } - }); + myResultsUpdateQueue.queue(new ProblemsComputedUpdate(element, problemsHolder)); } private void doCollectUsages(final ProjectStructureElement element) { @@ -92,18 +81,9 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { result.setResult(getUsagesInElement(element)); } }.execute().getResultObject(); - - invokeLater(new Runnable() { - @Override - public void run() { - if (myStopped.get() || usages == null) return; - - if (LOG.isDebugEnabled()) { - LOG.debug("updating usages for " + element); - } - updateUsages(element, usages); - } - }); + if (usages != null) { + myResultsUpdateQueue.queue(new UsagesCollectedUpdate(element, usages)); + } } private static List<ProjectStructureElementUsage> getUsagesInElement(final ProjectStructureElement element) { @@ -116,11 +96,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { addUsage(usage); } myElementWithNotCalculatedUsages.remove(element); - reportUnusedElements(); - } - - private static void invokeLater(Runnable runnable) { - SwingUtilities.invokeLater(runnable); + myResultsUpdateQueue.queue(new ReportUnusedElementsUpdate()); } public void queueUpdate(@NotNull final ProjectStructureElement element) { @@ -141,21 +117,28 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { } public void removeElement(ProjectStructureElement element) { - myElementWithNotCalculatedUsages.remove(element); - myElementsToShowWarningIfUnused.remove(element); - myWarningsAboutUnused.remove(element); - myProblemHolders.remove(element); - final Collection<ProjectStructureElementUsage> usages = mySourceElement2Usages.removeAll(element); - if (usages != null) { - for (ProjectStructureElementUsage usage : usages) { - myProblemHolders.remove(usage.getContainingElement()); + removeElements(Collections.singletonList(element)); + } + + public void removeElements(@NotNull List<? extends ProjectStructureElement> elements) { + myElementWithNotCalculatedUsages.removeAll(elements); + myElementsToShowWarningIfUnused.removeAll(elements); + for (ProjectStructureElement element : elements) { + myWarningsAboutUnused.remove(element); + myProblemHolders.remove(element); + final Collection<ProjectStructureElementUsage> usages = mySourceElement2Usages.removeAll(element); + if (usages != null) { + for (ProjectStructureElementUsage usage : usages) { + myProblemHolders.remove(usage.getContainingElement()); + } } + removeUsagesInElement(element); + myDispatcher.getMulticaster().problemsChanged(element); } - removeUsagesInElement(element); - myDispatcher.getMulticaster().problemsChanged(element); - reportUnusedElements(); + myResultsUpdateQueue.queue(new ReportUnusedElementsUpdate()); } + private void reportUnusedElements() { if (!myElementWithNotCalculatedUsages.isEmpty()) return; @@ -205,8 +188,10 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { LOG.debug("analyzer stopped"); myStopped.set(true); myAnalyzerQueue.cancelAllUpdates(); + myResultsUpdateQueue.cancelAllUpdates(); clearCaches(); myAnalyzerQueue.deactivate(); + myResultsUpdateQueue.deactivate(); } public void clearCaches() { @@ -232,6 +217,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { public void dispose() { myStopped.set(true); myAnalyzerQueue.cancelAllUpdates(); + myResultsUpdateQueue.cancelAllUpdates(); } @Nullable @@ -256,6 +242,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { public void reset() { LOG.debug("analyzer started"); myAnalyzerQueue.activate(); + myResultsUpdateQueue.activate(); myAnalyzerQueue.queue(new Update("reset") { @Override public void run() { @@ -270,9 +257,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { mySourceElement2Usages.clear(); myContainingElement2Usages.clear(); myElementWithNotCalculatedUsages.clear(); - if (myProjectConfigurationProblems != null) { - myProjectConfigurationProblems.clearProblems(); - } + myProjectConfigurationProblems.clearProblems(); } private class AnalyzeElementUpdate extends Update { @@ -312,4 +297,78 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { } } } + + private class UsagesCollectedUpdate extends Update { + private final ProjectStructureElement myElement; + private final List<ProjectStructureElementUsage> myUsages; + private final Object[] myEqualityObjects; + + public UsagesCollectedUpdate(ProjectStructureElement element, List<ProjectStructureElementUsage> usages) { + super(element); + myElement = element; + myUsages = usages; + myEqualityObjects = new Object[]{element, "usages collected"}; + } + + @NotNull + @Override + public Object[] getEqualityObjects() { + return myEqualityObjects; + } + + @Override + public void run() { + if (myStopped.get()) return; + + if (LOG.isDebugEnabled()) { + LOG.debug("updating usages for " + myElement); + } + updateUsages(myElement, myUsages); + } + } + + private class ProblemsComputedUpdate extends Update { + private final ProjectStructureElement myElement; + private final ProjectStructureProblemsHolderImpl myProblemsHolder; + private final Object[] myEqualityObjects; + + public ProblemsComputedUpdate(ProjectStructureElement element, ProjectStructureProblemsHolderImpl problemsHolder) { + super(element); + myElement = element; + myProblemsHolder = problemsHolder; + myEqualityObjects = new Object[]{element, "problems computed"}; + } + + @NotNull + @Override + public Object[] getEqualityObjects() { + return myEqualityObjects; + } + + @Override + public void run() { + if (myStopped.get()) return; + + if (LOG.isDebugEnabled()) { + LOG.debug("updating problems for " + myElement); + } + final ProjectStructureProblemDescription warning = myWarningsAboutUnused.get(myElement); + if (warning != null) { + myProblemsHolder.registerProblem(warning); + } + myProblemHolders.put(myElement, myProblemsHolder); + myDispatcher.getMulticaster().problemsChanged(myElement); + } + } + + private class ReportUnusedElementsUpdate extends Update { + private ReportUnusedElementsUpdate() { + super("unused elements"); + } + + @Override + public void run() { + reportUnusedElements(); + } + } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java index e11e2c016e56..8ee44f43c275 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java @@ -292,11 +292,14 @@ public class AnnotationsHighlightUtil { private static final ElementPattern<PsiElement> ANY_ANNOTATION_ALLOWED = psiElement().andOr( psiElement().withParent(PsiNameValuePair.class), psiElement().withParents(PsiArrayInitializerMemberValue.class, PsiNameValuePair.class), + psiElement().withParents(PsiArrayInitializerMemberValue.class, PsiAnnotationMethod.class), psiElement().withParent(PsiAnnotationMethod.class).afterLeaf(PsiKeyword.DEFAULT) ); @Nullable - public static HighlightInfo checkApplicability(@NotNull PsiAnnotation annotation, @NotNull LanguageLevel languageLevel,@NotNull PsiFile containingFile) { + public static HighlightInfo checkApplicability(@NotNull PsiAnnotation annotation, + @NotNull LanguageLevel languageLevel, + @NotNull PsiFile containingFile) { if (ANY_ANNOTATION_ALLOWED.accepts(annotation)) { return null; } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index 365dd5a89963..5946e8a0a44c 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -29,7 +29,6 @@ import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.JavaVersionService; -import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.pom.java.LanguageLevel; @@ -202,7 +201,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh public void visitAnnotation(PsiAnnotation annotation) { super.visitAnnotation(annotation); if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAnnotationFeature(annotation, myLanguageLevel, myFile)); - if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkApplicability(annotation, myLanguageLevel,myFile)); + if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkApplicability(annotation, myLanguageLevel, myFile)); if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkAnnotationType(annotation)); if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkMissingAttributes(annotation)); if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkTargetAnnotationDuplicates(annotation)); @@ -314,7 +313,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, resolveResult); if (expression.hasFormalParameterTypes()) { for (int i = 0; i < lambdaParameters.length; i++) { - if (!Comparing.equal(lambdaParameters[i].getType(), substitutor.substitute(parameters[i].getType()))) { + if (!PsiTypesUtil.compareTypes(lambdaParameters[i].getType(), substitutor.substitute(parameters[i].getType()), true)) { HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(lambdaParameters[i]) .descriptionAndTooltip(incompatibleTypesMessage) @@ -1080,7 +1079,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh final PsiTypeParameterListOwner owner = ((PsiTypeParameter)resolved).getOwner(); if (owner instanceof PsiClass) { final PsiClass outerClass = (PsiClass)owner; - if (!InheritanceUtil.hasEnclosingInstanceInScope(outerClass, ref, true, false)) { + if (!InheritanceUtil.hasEnclosingInstanceInScope(outerClass, ref, false, false)) { myHolder.add(HighlightClassUtil.reportIllegalEnclosingUsage(ref, aClass, (PsiClass)owner, ref)); } } @@ -1240,7 +1239,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh } } } - + if (!myHolder.hasErrorResults()) { myHolder.add(PsiMethodReferenceHighlightingUtil.checkRawConstructorReference(expression)); } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeArgumentsConditionalFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeArgumentsConditionalFix.java index f574b49dc551..09f879b0d795 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeArgumentsConditionalFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeArgumentsConditionalFix.java @@ -75,7 +75,7 @@ public class AddTypeArgumentsConditionalFix implements IntentionAction { public String fun(PsiTypeParameter parameter) { final PsiType substituteTypeParam = mySubstitutor.substitute(parameter); LOG.assertTrue(substituteTypeParam != null); - return substituteTypeParam.getCanonicalText(); + return GenericsUtil.eliminateWildcards(substituteTypeParam).getCanonicalText(); } }, ", ") + ">"; final PsiExpression expression = myExpression.getMethodExpression().getQualifierExpression(); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java index 2bc0a28871d8..558c3c0cef43 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java @@ -118,7 +118,7 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI .canBeMethodReferenceProblem(methods[0].getBody(), parameters, anonymousClass.getBaseClassType()); if (callExpression == null) return; final String methodRefText = - LambdaCanBeMethodReferenceInspection.createMethodReferenceText(callExpression, anonymousClass.getBaseClassType()); + LambdaCanBeMethodReferenceInspection.createMethodReferenceText(callExpression, anonymousClass.getBaseClassType(), parameters); if (methodRefText != null) { final String canonicalText = anonymousClass.getBaseClassType().getCanonicalText(); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java index 83783f5590e4..8a8a6db0752e 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java @@ -24,6 +24,7 @@ import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.ArrayUtilRt; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -114,8 +115,8 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp if (argumentList != null) { final PsiExpression[] expressions = argumentList.getExpressions(); - final PsiMethod psiMethod = methodCall.resolveMethod(); - final PsiClass containingClass; + PsiMethod psiMethod = methodCall.resolveMethod(); + PsiClass containingClass; boolean isConstructor; if (psiMethod == null) { isConstructor = true; @@ -131,6 +132,12 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp } if (containingClass == null) return null; boolean isReceiverType = PsiMethodReferenceUtil.isReceiverType(functionalInterfaceType, containingClass, psiMethod); + if (isReceiverType && psiMethod != null) { + PsiMethod nonAmbiguousMethod = ensureNonAmbiguousMethod(parameters, psiMethod); + if (nonAmbiguousMethod == null) return null; + psiMethod = nonAmbiguousMethod; + containingClass = nonAmbiguousMethod.getContainingClass(); + } final boolean staticOrValidConstructorRef; if (isConstructor) { staticOrValidConstructorRef = @@ -181,6 +188,12 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp } @Override + public void visitNewExpression(PsiNewExpression expression) { + usedInQualifier.set(true); + super.visitNewExpression(expression); + } + + @Override public void visitMethodCallExpression(PsiMethodCallExpression expression) { usedInQualifier.set(true); super.visitMethodCallExpression(expression); @@ -206,13 +219,35 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp } @Nullable - protected static String createMethodReferenceText(PsiElement element, PsiType functionalInterfaceType) { + private static PsiMethod ensureNonAmbiguousMethod(PsiParameter[] parameters, @NotNull PsiMethod psiMethod) { + String methodName = psiMethod.getName(); + PsiClass containingClass = psiMethod.getContainingClass(); + if (containingClass == null) return null; + for (PsiMethod method : containingClass.findMethodsByName(methodName, false)) { + PsiParameter[] candidateParams = method.getParameterList().getParameters(); + if (candidateParams.length == 1) { + if (TypeConversionUtil.areTypesConvertible(candidateParams[0].getType(), parameters[0].getType())) { + for (PsiMethod superMethod : psiMethod.findDeepestSuperMethods()) { + PsiMethod validSuperMethod = ensureNonAmbiguousMethod(parameters, superMethod); + if (validSuperMethod != null) return validSuperMethod; + } + return null; + } + } + } + return psiMethod; + } + + @Nullable + protected static String createMethodReferenceText(final PsiElement element, + final PsiType functionalInterfaceType, + final PsiParameter[] parameters) { String methodRefText = null; if (element instanceof PsiMethodCallExpression) { final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)element; final PsiMethod psiMethod = methodCall.resolveMethod(); if (psiMethod == null) return null; - final PsiClass containingClass = psiMethod.getContainingClass(); + PsiClass containingClass = psiMethod.getContainingClass(); LOG.assertTrue(containingClass != null); final PsiReferenceExpression methodExpression = methodCall.getMethodExpression(); final PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); @@ -221,8 +256,15 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp boolean isReceiverType = PsiMethodReferenceUtil.isReceiverType(functionalInterfaceType, containingClass, psiMethod); final String qualifier; if (isReceiverType) { - final PsiType qualifierExpressionType = qualifierExpression.getType(); - qualifier = qualifierExpressionType != null ? qualifierExpressionType.getCanonicalText() : getClassReferenceName(containingClass); + final PsiMethod nonAmbiguousMethod = ensureNonAmbiguousMethod(parameters, psiMethod); + LOG.assertTrue(nonAmbiguousMethod != null); + final PsiClass nonAmbiguousContainingClass = nonAmbiguousMethod.getContainingClass(); + if (!containingClass.equals(nonAmbiguousContainingClass)) { + qualifier = getClassReferenceName(nonAmbiguousContainingClass); + } else { + final PsiType qualifierExpressionType = qualifierExpression.getType(); + qualifier = qualifierExpressionType != null ? qualifierExpressionType.getCanonicalText() : getClassReferenceName(nonAmbiguousContainingClass); + } } else { qualifier = qualifierExpression.getText(); @@ -298,7 +340,8 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class); if (lambdaExpression == null) return; final PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType(); - final String methodRefText = createMethodReferenceText(element, functionalInterfaceType); + final String methodRefText = createMethodReferenceText(element, functionalInterfaceType, + lambdaExpression.getParameterList().getParameters()); if (methodRefText != null) { final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantSuppressInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantSuppressInspectionBase.java index ac49a6221597..f35609aabd5d 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantSuppressInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantSuppressInspectionBase.java @@ -43,7 +43,7 @@ import java.util.*; /** * @author cdr */ -public class RedundantSuppressInspection extends GlobalInspectionTool{ +public class RedundantSuppressInspectionBase extends GlobalInspectionTool { private BidirectionalMap<String, QuickFix> myQuickFixes = null; private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.RedundantSuppressInspection"); @@ -87,7 +87,7 @@ public class RedundantSuppressInspection extends GlobalInspectionTool{ @NotNull final ProblemDescriptionsProcessor problemDescriptionsProcessor) { globalContext.getRefManager().iterate(new RefJavaVisitor() { @Override public void visitClass(@NotNull RefClass refClass) { - if (!globalContext.shouldCheck(refClass, RedundantSuppressInspection.this)) return; + if (!globalContext.shouldCheck(refClass, RedundantSuppressInspectionBase.this)) return; CommonProblemDescriptor[] descriptors = checkElement(refClass, manager, globalContext.getProject()); if (descriptors != null) { for (CommonProblemDescriptor descriptor : descriptors) { @@ -192,7 +192,7 @@ public class RedundantSuppressInspection extends GlobalInspectionTool{ PsiFile file = psiElement.getContainingFile(); final AnalysisScope scope = new AnalysisScope(file); - final GlobalInspectionContextBase globalContext = new GlobalInspectionContextBase(file.getProject()); + final GlobalInspectionContextBase globalContext = createContext(file); globalContext.setCurrentScope(scope); final RefManagerImpl refManager = (RefManagerImpl)globalContext.getRefManager(); refManager.inspectionReadActionStarted(); @@ -314,6 +314,10 @@ public class RedundantSuppressInspection extends GlobalInspectionTool{ return result.toArray(new ProblemDescriptor[result.size()]); } + protected GlobalInspectionContextBase createContext(PsiFile file) { + return new GlobalInspectionContextBase(file.getProject()); + } + protected InspectionToolWrapper[] getInspectionTools(PsiElement psiElement, @NotNull InspectionManager manager) { ModifiableModel model = InspectionProjectProfileManager.getInstance(manager.getProject()).getInspectionProfile().getModifiableModel(); InspectionProfileWrapper profile = new InspectionProfileWrapper((InspectionProfile)model); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java index 8d845ff3023e..22c919caecd0 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java @@ -94,6 +94,10 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { return null; } + PsiElement parent = codeFragment.getParent(); + if (parent instanceof PsiLambdaExpression && codeFragment instanceof PsiExpression) { + addInstruction(new CheckReturnValueInstruction(codeFragment)); + } myCurrentFlow.setFields(myFields.toArray(new DfaVariableValue[myFields.size()])); addInstruction(new ReturnInstruction(false)); @@ -528,6 +532,15 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { finishElement(statement); } + @Override + public void visitLambdaExpression(PsiLambdaExpression expression) { + startElement(expression); + DfaValue dfaValue = myFactory.createValue(expression); + addInstruction(new PushInstruction(dfaValue, expression)); + addInstruction(new LambdaInstruction(expression)); + finishElement(expression); + } + @Override public void visitReturnStatement(PsiReturnStatement statement) { startElement(statement); @@ -538,7 +551,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { if (method != null) { generateBoxingUnboxingInstructionFor(returnValue, method.getReturnType()); } - addInstruction(new CheckReturnValueInstruction(statement)); + addInstruction(new CheckReturnValueInstruction(returnValue)); } returnCheckingFinally(); @@ -1874,7 +1887,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { } final PsiTypeElement typeElement = castExpression.getCastType(); - if (typeElement != null && operand != null) { + if (typeElement != null && operand != null && operand.getType() != null) { if (typeElement.getType() instanceof PsiPrimitiveType && UnnecessaryExplicitNumericCastInspection.isPrimitiveNumericCastNecessary(castExpression)) { addInstruction(new PopInstruction()); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java index c6314f7d9bb1..305085c459c8 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java @@ -192,7 +192,7 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { } @Nullable - private LocalQuickFix[] createNPEFixes(PsiExpression qualifier, PsiExpression expression) { + private LocalQuickFix[] createNPEFixes(PsiExpression qualifier, PsiExpression expression, boolean onTheFly) { if (qualifier == null || expression == null) return null; if (qualifier instanceof PsiMethodCallExpression) return null; if (qualifier instanceof PsiLiteralExpression && ((PsiLiteralExpression)qualifier).getValue() == null) return null; @@ -208,7 +208,7 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { fixes.add(new AddAssertStatementFix(binary)); } - addSurroundWithIfFix(qualifier, fixes); + addSurroundWithIfFix(qualifier, fixes, onTheFly); if (ReplaceWithTernaryOperatorFix.isAvailable(qualifier, expression)) { fixes.add(new ReplaceWithTernaryOperatorFix(qualifier)); @@ -221,7 +221,7 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { } } - protected void addSurroundWithIfFix(PsiExpression qualifier, List<LocalQuickFix> fixes) { + protected void addSurroundWithIfFix(PsiExpression qualifier, List<LocalQuickFix> fixes, boolean onTheFly) { } private void createDescription(StandardDataFlowRunner runner, ProblemsHolder holder, DataFlowInstructionVisitor visitor) { @@ -238,7 +238,7 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { HashSet<PsiElement> reportedAnchors = new HashSet<PsiElement>(); for (PsiElement element : visitor.getProblems(NullabilityProblem.callNPE)) { if (reportedAnchors.add(element)) { - reportCallMayProduceNpe(holder, (PsiMethodCallExpression)element); + reportCallMayProduceNpe(holder, (PsiMethodCallExpression)element, holder.isOnTheFly()); } } for (PsiElement element : visitor.getProblems(NullabilityProblem.fieldAccessNPE)) { @@ -340,7 +340,7 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { final String text = isNullLiteralExpression(expr) ? "Passing <code>null</code> argument to non annotated parameter" : "Argument <code>#ref</code> #loc might be null but passed to non annotated parameter"; - LocalQuickFix[] fixes = createNPEFixes((PsiExpression)expr, (PsiExpression)expr); + LocalQuickFix[] fixes = createNPEFixes((PsiExpression)expr, (PsiExpression)expr, holder.isOnTheFly()); final PsiElement parent = expr.getParent(); if (parent instanceof PsiExpressionList) { final int idx = ArrayUtilRt.find(((PsiExpressionList)parent).getExpressions(), expr); @@ -364,8 +364,8 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { } } - private void reportCallMayProduceNpe(ProblemsHolder holder, PsiMethodCallExpression callExpression) { - LocalQuickFix[] fix = createNPEFixes(callExpression.getMethodExpression().getQualifierExpression(), callExpression); + private void reportCallMayProduceNpe(ProblemsHolder holder, PsiMethodCallExpression callExpression, boolean onTheFly) { + LocalQuickFix[] fix = createNPEFixes(callExpression.getMethodExpression().getQualifierExpression(), callExpression, onTheFly); holder.registerProblem(callExpression, InspectionsBundle.message("dataflow.message.npe.method.invocation"), @@ -374,13 +374,13 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { private void reportFieldAccessMayProduceNpe(ProblemsHolder holder, PsiElement elementToAssert, PsiExpression expression) { if (expression instanceof PsiArrayAccessExpression) { - LocalQuickFix[] fix = createNPEFixes((PsiExpression)elementToAssert, expression); + LocalQuickFix[] fix = createNPEFixes((PsiExpression)elementToAssert, expression, holder.isOnTheFly()); holder.registerProblem(expression, InspectionsBundle.message("dataflow.message.npe.array.access"), fix); } else { - LocalQuickFix[] fix = createNPEFixes((PsiExpression)elementToAssert, expression); + LocalQuickFix[] fix = createNPEFixes((PsiExpression)elementToAssert, expression, holder.isOnTheFly()); assert elementToAssert != null; holder.registerProblem(elementToAssert, InspectionsBundle.message("dataflow.message.npe.field.access"), @@ -454,7 +454,7 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { final String text = isNullLiteralExpression(expr) ? InspectionsBundle.message("dataflow.message.passing.null.argument") : InspectionsBundle.message("dataflow.message.passing.nullable.argument"); - LocalQuickFix[] fixes = createNPEFixes((PsiExpression)expr, (PsiExpression)expr); + LocalQuickFix[] fixes = createNPEFixes((PsiExpression)expr, (PsiExpression)expr, holder.isOnTheFly()); holder.registerProblem(expr, text, fixes); } } @@ -479,8 +479,8 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { private static void reportNullableReturns(StandardDataFlowRunner runner, DataFlowInstructionVisitor visitor, ProblemsHolder holder, Set<PsiElement> reportedAnchors) { for (PsiElement statement : visitor.getProblems(NullabilityProblem.nullableReturn)) { - final PsiExpression expr = ((PsiReturnStatement)statement).getReturnValue(); - assert expr != null; + assert statement instanceof PsiExpression; + final PsiExpression expr = (PsiExpression)statement; if (!reportedAnchors.add(expr)) continue; if (runner.isInNotNullMethod()) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java index 09c4612b0e6e..6c5c9096fac1 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java @@ -226,6 +226,10 @@ public class DataFlowRunner { } } } + else if (instruction instanceof LambdaInstruction) { + PsiLambdaExpression lambdaExpression = ((LambdaInstruction)instruction).getLambdaExpression(); + registerNestedClosures(instructionState, lambdaExpression); + } else if (instruction instanceof EmptyInstruction) { PsiElement anchor = ((EmptyInstruction)instruction).getAnchor(); if (anchor instanceof PsiDeclarationStatement) { @@ -255,6 +259,14 @@ public class DataFlowRunner { myNestedClosures.putValue(field, createClosureState(state)); } } + + private void registerNestedClosures(DfaInstructionState instructionState, PsiLambdaExpression expr) { + DfaMemoryState state = instructionState.getMemoryState(); + PsiElement body = expr.getBody(); + if (body != null) { + myNestedClosures.putValue(body, createClosureState(state)); + } + } protected ControlFlowAnalyzer createControlFlowAnalyzer() { return new ControlFlowAnalyzer(myValueFactory); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java index b1d3203414a9..0b9f0b010911 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java @@ -54,6 +54,10 @@ public abstract class InstructionVisitor { return nextInstruction(instruction, runner, memState); } + public DfaInstructionState[] visitLambdaExpression(LambdaInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) { + return nextInstruction(instruction, runner, memState); + } + public DfaInstructionState[] visitConditionalGoto(ConditionalGotoInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) { DfaValue cond = memState.pop(); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java index 3ada3e849647..2652c6ff19f6 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java @@ -27,10 +27,7 @@ package com.intellij.codeInspection.dataFlow; import com.intellij.codeInsight.NullableNotNullManager; import com.intellij.codeInspection.dataFlow.instructions.InstanceofInstruction; import com.intellij.codeInspection.dataFlow.instructions.Instruction; -import com.intellij.psi.CommonClassNames; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiMethod; -import com.intellij.psi.PsiType; +import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; import java.util.HashSet; @@ -49,13 +46,23 @@ public class StandardDataFlowRunner extends DataFlowRunner { @Override protected void prepareAnalysis(@NotNull PsiElement psiBlock, Iterable<DfaMemoryState> initialStates) { - myIsInMethod = psiBlock.getParent() instanceof PsiMethod; + PsiElement parent = psiBlock.getParent(); + myIsInMethod = parent instanceof PsiMethod; if (myIsInMethod) { - PsiMethod method = (PsiMethod)psiBlock.getParent(); + PsiMethod method = (PsiMethod)parent; PsiType returnType = method.getReturnType(); myInNullableMethod = NullableNotNullManager.isNullable(method) || returnType != null && returnType.equalsToText(CommonClassNames.JAVA_LANG_VOID); myInNotNullMethod = NullableNotNullManager.isNotNull(method); + } else if (parent instanceof PsiLambdaExpression) { + PsiMethod method = LambdaUtil.getFunctionalInterfaceMethod(((PsiLambdaExpression)parent).getFunctionalInterfaceType()); + if (method != null) { + myIsInMethod = true; + PsiType returnType = method.getReturnType(); + myInNullableMethod = NullableNotNullManager.isNullable(method) || + returnType != null && returnType.equalsToText(CommonClassNames.JAVA_LANG_VOID); + myInNotNullMethod = NullableNotNullManager.isNotNull(method); + } } myCCEInstructions.clear(); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/CheckReturnValueInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/CheckReturnValueInstruction.java index a668a7bdd0e2..6d17463b1318 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/CheckReturnValueInstruction.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/CheckReturnValueInstruction.java @@ -19,16 +19,16 @@ import com.intellij.codeInspection.dataFlow.DataFlowRunner; import com.intellij.codeInspection.dataFlow.DfaInstructionState; import com.intellij.codeInspection.dataFlow.DfaMemoryState; import com.intellij.codeInspection.dataFlow.InstructionVisitor; -import com.intellij.psi.PsiReturnStatement; +import com.intellij.psi.PsiElement; /** * @author max */ public class CheckReturnValueInstruction extends Instruction { - private final PsiReturnStatement myReturn; + private final PsiElement myReturnValue; - public CheckReturnValueInstruction(final PsiReturnStatement aReturn) { - myReturn = aReturn; + public CheckReturnValueInstruction(final PsiElement returnValue) { + myReturnValue = returnValue; } @Override @@ -36,8 +36,8 @@ public class CheckReturnValueInstruction extends Instruction { return visitor.visitCheckReturnValue(this, runner, stateBefore); } - public PsiReturnStatement getReturn() { - return myReturn; + public PsiElement getReturn() { + return myReturnValue; } public String toString() { diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/LambdaInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/LambdaInstruction.java new file mode 100644 index 000000000000..a0cedb95d948 --- /dev/null +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/LambdaInstruction.java @@ -0,0 +1,44 @@ +/* + * 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.instructions; + +import com.intellij.codeInspection.dataFlow.DataFlowRunner; +import com.intellij.codeInspection.dataFlow.DfaInstructionState; +import com.intellij.codeInspection.dataFlow.DfaMemoryState; +import com.intellij.codeInspection.dataFlow.InstructionVisitor; +import com.intellij.psi.PsiLambdaExpression; + +public class LambdaInstruction extends Instruction { + private final PsiLambdaExpression myLambdaExpression; + + public LambdaInstruction(PsiLambdaExpression lambdaExpression) { + myLambdaExpression = lambdaExpression; + } + + public PsiLambdaExpression getLambdaExpression() { + return myLambdaExpression; + } + + @Override + public DfaInstructionState[] accept(DataFlowRunner runner, DfaMemoryState stateBefore, InstructionVisitor visitor) { + return visitor.visitLambdaExpression(this, runner, stateBefore); + } + + @Override + public String toString() { + return "LambdaInstruction"; + } +} diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dependencyViolation/DependencyInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dependencyViolation/DependencyInspectionBase.java index e39bc8e1ac1b..bd13202958a8 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dependencyViolation/DependencyInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dependencyViolation/DependencyInspectionBase.java @@ -30,7 +30,7 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -public class DependencyInspectionBase extends AbstractBaseJavaLocalInspectionTool { +public class DependencyInspectionBase extends BaseJavaBatchLocalInspectionTool { private static final String GROUP_DISPLAY_NAME = ""; private static final String DISPLAY_NAME = InspectionsBundle.message("illegal.package.dependencies"); @NonNls private static final String SHORT_NAME = "Dependency"; diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspectionBase.java index ca03e7fe12a9..33cd0040462b 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspectionBase.java @@ -44,7 +44,7 @@ import org.jetbrains.annotations.Nullable; import java.util.*; -public class JavaDocLocalInspectionBase extends AbstractBaseJavaLocalInspectionTool { +public class JavaDocLocalInspectionBase extends BaseJavaBatchLocalInspectionTool { private static final Logger LOG = Logger.getInstance("com.intellij.codeInspection.javaDoc.JavaDocLocalInspectionBase"); @NonNls protected static final String NONE = "none"; @NonNls protected static final String PUBLIC = "public"; diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/javaDoc/JavaDocReferenceInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/javaDoc/JavaDocReferenceInspectionBase.java index 6a9aa1b37ed4..bfe239891fff 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/javaDoc/JavaDocReferenceInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/javaDoc/JavaDocReferenceInspectionBase.java @@ -31,7 +31,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -public class JavaDocReferenceInspectionBase extends AbstractBaseJavaLocalInspectionTool { +public class JavaDocReferenceInspectionBase extends BaseJavaBatchLocalInspectionTool { @NonNls private static final String SHORT_NAME = "JavadocReference"; private static ProblemDescriptor createDescriptor(@NotNull PsiElement element, String template, InspectionManager manager, diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java b/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java index 028e9b7a7e9d..d4cff693643a 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java @@ -18,6 +18,7 @@ package com.intellij.codeInspection.localCanBeFinal; import com.intellij.codeInsight.FileModificationService; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.codeInspection.*; +import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.psi.*; @@ -44,6 +45,8 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool { public boolean REPORT_VARIABLES = true; public boolean REPORT_PARAMETERS = true; + public boolean REPORT_CATCH_PARAMETERS = true; + public boolean REPORT_FOREACH_PARAMETERS = true; private final LocalQuickFix myQuickFix; @NonNls public static final String SHORT_NAME = "LocalCanBeFinal"; @@ -148,6 +151,7 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool { @Override public void visitCatchSection(PsiCatchSection section) { super.visitCatchSection(section); + if (!REPORT_CATCH_PARAMETERS) return; final PsiParameter parameter = section.getParameter(); if (PsiTreeUtil.getParentOfType(parameter, PsiClass.class) != PsiTreeUtil.getParentOfType(body, PsiClass.class)) { return; @@ -164,6 +168,7 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool { @Override public void visitForeachStatement(PsiForeachStatement statement) { super.visitForeachStatement(statement); + if (!REPORT_FOREACH_PARAMETERS) return; final PsiParameter param = statement.getIterationParameter(); if (PsiTreeUtil.getParentOfType(param, PsiClass.class) != PsiTreeUtil.getParentOfType(body, PsiClass.class)) { return; @@ -219,7 +224,7 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool { } }); - if (body.getParent() instanceof PsiMethod && isReportParameters()) { + if (body.getParent() instanceof PsiMethod && REPORT_PARAMETERS) { final PsiMethod method = (PsiMethod)body.getParent(); if (!(method instanceof SyntheticElement)) { // e.g. JspHolderMethod Collections.addAll(result, method.getParameterList().getParameters()); @@ -231,6 +236,16 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool { if (shouldBeIgnored(variable)) { iterator.remove(); } + final PsiElement parent = variable.getParent(); + if (!(parent instanceof PsiDeclarationStatement)) { + continue; + } + final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)parent; + final PsiElement[] elements = declarationStatement.getDeclaredElements(); + final PsiElement grandParent = parent.getParent(); + if (elements.length > 1 && grandParent instanceof PsiForStatement) { + iterator.remove(); // do not report when more than 1 variable declared in for loop + } } for (PsiVariable writtenVariable : writtenVariables) { @@ -261,19 +276,21 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool { private boolean shouldBeIgnored(PsiVariable psiVariable) { if (psiVariable.hasModifierProperty(PsiModifier.FINAL)) return true; - return isLocalVariable(psiVariable) ? !isReportVariables() : !isReportParameters(); - } - - private static boolean isLocalVariable(PsiVariable variable) { - if (variable instanceof PsiLocalVariable) { - return true; + if (psiVariable instanceof PsiLocalVariable) { + return !REPORT_VARIABLES; } - if (!(variable instanceof PsiParameter)) { - return false; + if (psiVariable instanceof PsiParameter) { + final PsiParameter parameter = (PsiParameter)psiVariable; + final PsiElement declarationScope = parameter.getDeclarationScope(); + if (declarationScope instanceof PsiCatchSection) { + return !REPORT_CATCH_PARAMETERS; + } + else if (declarationScope instanceof PsiForeachStatement) { + return !REPORT_FOREACH_PARAMETERS; + } + return !REPORT_PARAMETERS; } - final PsiParameter parameter = (PsiParameter)variable; - final PsiElement declarationScope = parameter.getDeclarationScope(); - return !(declarationScope instanceof PsiMethod) && !(declarationScope instanceof PsiLambdaExpression); + return true; } @Override @@ -326,55 +343,12 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool { @Override public JComponent createOptionsPanel() { - return new OptionsPanel(); - } - - private boolean isReportVariables() { - return REPORT_VARIABLES; - } - - private boolean isReportParameters() { - return REPORT_PARAMETERS; - } - - private class OptionsPanel extends JPanel { - private final JCheckBox myReportVariablesCheckbox; - private final JCheckBox myReportParametersCheckbox; - - private OptionsPanel() { - super(new GridBagLayout()); - - GridBagConstraints gc = new GridBagConstraints(); - gc.weighty = 0; - gc.weightx = 1; - gc.fill = GridBagConstraints.HORIZONTAL; - gc.anchor = GridBagConstraints.NORTHWEST; - - - myReportVariablesCheckbox = new JCheckBox(InspectionsBundle.message("inspection.local.can.be.final.option")); - myReportVariablesCheckbox.setSelected(REPORT_VARIABLES); - myReportVariablesCheckbox.getModel().addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - REPORT_VARIABLES = myReportVariablesCheckbox.isSelected(); - } - }); - gc.gridy = 0; - add(myReportVariablesCheckbox, gc); - - myReportParametersCheckbox = new JCheckBox(InspectionsBundle.message("inspection.local.can.be.final.option1")); - myReportParametersCheckbox.setSelected(REPORT_PARAMETERS); - myReportParametersCheckbox.getModel().addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - REPORT_PARAMETERS = myReportParametersCheckbox.isSelected(); - } - }); - - gc.weighty = 1; - gc.gridy++; - add(myReportParametersCheckbox, gc); - } + final MultipleCheckboxOptionsPanel panel = new MultipleCheckboxOptionsPanel(this); + panel.addCheckbox(InspectionsBundle.message("inspection.local.can.be.final.option"), "REPORT_VARIABLES"); + panel.addCheckbox(InspectionsBundle.message("inspection.local.can.be.final.option1"), "REPORT_PARAMETERS"); + panel.addCheckbox(InspectionsBundle.message("inspection.local.can.be.final.option2"), "REPORT_CATCH_PARAMETERS"); + panel.addCheckbox(InspectionsBundle.message("inspection.local.can.be.final.option3"), "REPORT_FOREACH_PARAMETERS"); + return panel; } @Override diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/miscGenerics/RedundantTypeArgsInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/miscGenerics/RedundantTypeArgsInspection.java index bb3c4ea3b8a9..27704329d49c 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/miscGenerics/RedundantTypeArgsInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/miscGenerics/RedundantTypeArgsInspection.java @@ -74,14 +74,18 @@ public class RedundantTypeArgsInspection extends GenericsInspectionToolBase { public ProblemDescriptor[] getDescriptions(@NotNull PsiElement place, @NotNull final InspectionManager inspectionManager, boolean isOnTheFly) { final List<ProblemDescriptor> problems = new ArrayList<ProblemDescriptor>(); place.accept(new JavaRecursiveElementWalkingVisitor() { - @Override public void visitMethodCallExpression(PsiMethodCallExpression expression) { + @Override + public void visitMethodCallExpression(PsiMethodCallExpression expression) { + super.visitMethodCallExpression(expression); final PsiType[] typeArguments = expression.getTypeArguments(); if (typeArguments.length > 0) { checkCallExpression(expression.getMethodExpression(), typeArguments, expression, inspectionManager, problems); } } - @Override public void visitNewExpression(PsiNewExpression expression) { + @Override + public void visitNewExpression(PsiNewExpression expression) { + super.visitNewExpression(expression); final PsiType[] typeArguments = expression.getTypeArguments(); if (typeArguments.length > 0) { final PsiJavaCodeReferenceElement classReference = expression.getClassReference(); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/suspiciousNameCombination/SuspiciousNameCombinationInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/suspiciousNameCombination/SuspiciousNameCombinationInspectionBase.java index e12f10cdbc53..72b71c0260b3 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/suspiciousNameCombination/SuspiciousNameCombinationInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/suspiciousNameCombination/SuspiciousNameCombinationInspectionBase.java @@ -117,7 +117,8 @@ public class SuspiciousNameCombinationInspectionBase extends BaseJavaBatchLocalI PsiExpression expr = variable.getInitializer(); if (expr instanceof PsiReferenceExpression) { PsiReferenceExpression refExpr = (PsiReferenceExpression) expr; - checkCombination(variable, variable.getName(), refExpr.getReferenceName(), "suspicious.name.assignment"); + PsiIdentifier nameIdentifier = variable.getNameIdentifier(); + checkCombination(nameIdentifier != null ? nameIdentifier : variable, variable.getName(), refExpr.getReferenceName(), "suspicious.name.assignment"); } } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspectionBase.java index bb8556d968b5..276b451276ca 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspectionBase.java @@ -18,10 +18,7 @@ package com.intellij.codeInspection.varScopeCanBeNarrowed; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.codeInsight.daemon.ImplicitUsageProvider; -import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool; -import com.intellij.codeInspection.InspectionsBundle; -import com.intellij.codeInspection.LocalQuickFix; -import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.codeInspection.*; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.JDOMExternalizableStringList; @@ -41,7 +38,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; -public class FieldCanBeLocalInspectionBase extends AbstractBaseJavaLocalInspectionTool { +public class FieldCanBeLocalInspectionBase extends BaseJavaBatchLocalInspectionTool { @NonNls public static final String SHORT_NAME = "FieldCanBeLocal"; public final JDOMExternalizableStringList EXCLUDE_ANNOS = new JDOMExternalizableStringList(); public boolean IGNORE_FIELDS_USED_IN_MULTIPLE_METHODS = true; diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/ParameterCanBeLocalInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/ParameterCanBeLocalInspectionBase.java index 8ea58d6ed98f..7c9cd309fd14 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/ParameterCanBeLocalInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/ParameterCanBeLocalInspectionBase.java @@ -26,7 +26,7 @@ import org.jetbrains.annotations.Nullable; import java.util.*; -public class ParameterCanBeLocalInspectionBase extends AbstractBaseJavaLocalInspectionTool { +public class ParameterCanBeLocalInspectionBase extends BaseJavaBatchLocalInspectionTool { @NonNls public static final String SHORT_NAME = "ParameterCanBeLocal"; @NotNull diff --git a/java/java-analysis-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java b/java/java-analysis-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java index 7ee3d7bb35ca..2c427bd93254 100644 --- a/java/java-analysis-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java +++ b/java/java-analysis-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java @@ -49,7 +49,7 @@ public class JavaSyntaxHighlighterFactory extends SyntaxHighlighterFactory imple if (project != null && file != null) { PsiFile psiFile = PsiManager.getInstance(project).findFile(file); if (psiFile instanceof ClsFileImpl) { - LanguageLevel sourceLevel = ((ClsFileImpl)psiFile).getSourceLanguageLevel(); + LanguageLevel sourceLevel = ((ClsFileImpl)psiFile).getLanguageLevel(); return new JavaFileHighlighter(sourceLevel); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java b/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java index 2367ce3deb11..81cb9b5e1185 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java @@ -193,14 +193,14 @@ public class AllClassesGetter { private static String getPackagePrefix(final PsiElement context, final int offset) { - final String fileText = context.getContainingFile().getText(); + final CharSequence fileText = context.getContainingFile().getViewProvider().getContents(); int i = offset - 1; while (i >= 0) { final char c = fileText.charAt(i); if (!Character.isJavaIdentifierPart(c) && c != '.') break; i--; } - String prefix = fileText.substring(i + 1, offset); + String prefix = fileText.subSequence(i + 1, offset).toString(); final int j = prefix.lastIndexOf('.'); return j > 0 ? prefix.substring(0, j) : ""; } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java index aa1293ad42e8..bcfa4f0d55cd 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java @@ -94,7 +94,20 @@ public class JavaSmartCompletionContributor extends CompletionContributor { @Override public boolean accepts(@NotNull PsiElement element, ProcessingContext context) { final PsiElement rulezzRef = element.getParent(); - return rulezzRef != null && LambdaUtil.isValidLambdaContext(rulezzRef.getParent()); + return rulezzRef != null && + rulezzRef instanceof PsiReferenceExpression && + ((PsiReferenceExpression)rulezzRef).getQualifier() == null && + LambdaUtil.isValidLambdaContext(rulezzRef.getParent()); + }}); + + static final PsiElementPattern.Capture<PsiElement> METHOD_REFERENCE = psiElement().with(new PatternCondition<PsiElement>("METHOD_REFERENCE_CONTEXT") { + @Override + public boolean accepts(@NotNull PsiElement element, ProcessingContext context) { + final PsiElement rulezzRef = element.getParent(); + return rulezzRef != null && + rulezzRef instanceof PsiMethodReferenceExpression && + ((PsiReferenceExpression)rulezzRef).getQualifier() != element && + LambdaUtil.isValidLambdaContext(rulezzRef.getParent()); }}); @Nullable @@ -319,6 +332,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor { }); extend(CompletionType.SMART, LAMBDA, new LambdaCompletionProvider()); + extend(CompletionType.SMART, METHOD_REFERENCE, new MethodReferenceCompletionProvider()); } private static void addExpectedTypeMembers(CompletionParameters params, diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/MethodReferenceCompletionProvider.java b/java/java-impl/src/com/intellij/codeInsight/completion/MethodReferenceCompletionProvider.java new file mode 100644 index 000000000000..dbd2fc8ef3c6 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/completion/MethodReferenceCompletionProvider.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.completion; + +import com.intellij.codeInsight.ExpectedTypeInfo; +import com.intellij.codeInsight.ExpectedTypeInfoImpl; +import com.intellij.codeInsight.TailType; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.*; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.Consumer; +import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; + +public class MethodReferenceCompletionProvider extends CompletionProvider<CompletionParameters> { + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull final CompletionResultSet result) { + if (!PsiUtil.isLanguageLevel8OrHigher(parameters.getOriginalFile())) return; + final ExpectedTypeInfo[] expectedTypes = JavaSmartCompletionContributor.getExpectedTypes(parameters); + for (ExpectedTypeInfo expectedType : expectedTypes) { + final PsiType defaultType = expectedType.getDefaultType(); + if (LambdaHighlightingUtil.checkInterfaceFunctional(defaultType) == null) { + final PsiType returnType = LambdaUtil.getFunctionalInterfaceReturnType(defaultType); + if (returnType != null) { + final ExpectedTypeInfoImpl typeInfo = + new ExpectedTypeInfoImpl(returnType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, returnType, TailType.UNKNOWN, null, + ExpectedTypeInfoImpl.NULL); + Consumer<LookupElement> noTypeCheck = new Consumer<LookupElement>() { + @Override + public void consume(final LookupElement lookupElement) { + result.addElement(lookupElement); + } + }; + + final Runnable runnable = ReferenceExpressionCompletionContributor + .fillCompletionVariants(new JavaSmartCompletionParameters(parameters, typeInfo), noTypeCheck); + if (runnable != null) { + runnable.run(); + } + } + } + } + } +} diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java index e58de2929ee1..8f854b1d8b2b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java @@ -246,7 +246,10 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil { public static void annotateOnOverrideImplement(PsiMethod method, PsiClass targetClass, PsiMethod overridden, boolean insertOverride) { if (insertOverride && canInsertOverride(overridden, targetClass)) { - AddAnnotationPsiFix.addPhysicalAnnotation(Override.class.getName(), PsiNameValuePair.EMPTY_ARRAY, method.getModifierList()); + final String overrideAnnotationName = Override.class.getName(); + if (!AnnotationUtil.isAnnotated(method, overrideAnnotationName, false, true)) { + AddAnnotationPsiFix.addPhysicalAnnotation(overrideAnnotationName, PsiNameValuePair.EMPTY_ARRAY, method.getModifierList()); + } } final Module module = ModuleUtilCore.findModuleForPsiElement(targetClass); final GlobalSearchScope moduleScope = module != null ? GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module) : null; diff --git a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightExceptionsHandler.java b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightExceptionsHandler.java index 495bad2981b6..bd57f733a72b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightExceptionsHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightExceptionsHandler.java @@ -89,7 +89,9 @@ public class HighlightExceptionsHandler extends HighlightUsagesHandlerBase<PsiCl } else if (psiExpression instanceof PsiNewExpression) { PsiJavaCodeReferenceElement ref = ((PsiNewExpression)psiExpression).getClassReference(); - addOccurrence(ref); + if (ref != null) { + addOccurrence(ref); + } } else { addOccurrence(statement.getException()); diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java index 63e9ba0c724b..427383c9007f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java @@ -228,10 +228,15 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc PsiExpression arg = args[j]; assert parm.isValid(); assert arg.isValid(); - PsiType parmType = substitutor.substitute(parm.getType()); + PsiType parmType = parm.getType(); PsiType argType = arg.getType(); + if (argType == null) continue; + if (parmType instanceof PsiEllipsisType && parmType.getArrayDimensions() == argType.getArrayDimensions() + 1) { + parmType = ((PsiEllipsisType)parmType).getComponentType(); + } + parmType = substitutor.substitute(parmType); - if (argType != null && !parmType.isAssignableFrom(argType)) { + if (!parmType.isAssignableFrom(argType)) { return false; } } diff --git a/java/java-impl/src/com/intellij/codeInspection/RedundantSuppressInspection.java b/java/java-impl/src/com/intellij/codeInspection/RedundantSuppressInspection.java new file mode 100644 index 000000000000..22d61cb6e02e --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInspection/RedundantSuppressInspection.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInspection; + +import com.intellij.codeInspection.ex.GlobalInspectionContextBase; +import com.intellij.codeInspection.ex.InspectionManagerEx; +import com.intellij.psi.PsiFile; + +/** + * User: anna + * Date: 11/27/13 + */ +public class RedundantSuppressInspection extends RedundantSuppressInspectionBase { + @Override + protected GlobalInspectionContextBase createContext(PsiFile file) { + final InspectionManagerEx inspectionManagerEx = ((InspectionManagerEx)InspectionManager.getInstance(file.getProject())); + return inspectionManagerEx.createNewGlobalContext(false); + } +} diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java index bb3354bdf262..b1c04213a8b6 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java @@ -35,8 +35,8 @@ import java.util.List; public class DataFlowInspection extends DataFlowInspectionBase { @Override - protected void addSurroundWithIfFix(PsiExpression qualifier, List<LocalQuickFix> fixes) { - if (SurroundWithIfFix.isAvailable(qualifier)) { + protected void addSurroundWithIfFix(PsiExpression qualifier, List<LocalQuickFix> fixes, boolean onTheFly) { + if (onTheFly && SurroundWithIfFix.isAvailable(qualifier)) { fixes.add(new SurroundWithIfFix(qualifier)); } } diff --git a/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/FileHeaderChecker.java b/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/FileHeaderChecker.java index ffdd14fc0aa8..85ccbf943056 100644 --- a/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/FileHeaderChecker.java +++ b/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/FileHeaderChecker.java @@ -55,7 +55,7 @@ public class FileHeaderChecker { .getDefaultTemplate(FileTemplateManager.FILE_HEADER_TEMPLATE_NAME), file.getProject(), offsetToProperty ); - Matcher matcher = pattern.matcher(file.getText()); + Matcher matcher = pattern.matcher(file.getViewProvider().getContents()); if (matcher.matches()) { final int startOffset = matcher.start(1); final int endOffset = matcher.end(1); diff --git a/java/java-impl/src/com/intellij/ide/projectView/actions/MarkGeneratedSourceRootAction.java b/java/java-impl/src/com/intellij/ide/projectView/actions/MarkGeneratedSourceRootAction.java index e56a43233581..2106f17dff36 100644 --- a/java/java-impl/src/com/intellij/ide/projectView/actions/MarkGeneratedSourceRootAction.java +++ b/java/java-impl/src/com/intellij/ide/projectView/actions/MarkGeneratedSourceRootAction.java @@ -35,7 +35,7 @@ import org.jetbrains.jps.model.java.JpsJavaExtensionService; public class MarkGeneratedSourceRootAction extends MarkRootActionBase { public MarkGeneratedSourceRootAction() { Presentation presentation = getTemplatePresentation(); - presentation.setIcon(AllIcons.Modules.SourceRoot); + presentation.setIcon(AllIcons.Modules.GeneratedSourceRoot); presentation.setText("Generated Sources Root"); presentation.setDescription("Mark directory as a source root for generated files"); } diff --git a/java/java-impl/src/com/intellij/javadoc/JavadocConfiguration.java b/java/java-impl/src/com/intellij/javadoc/JavadocConfiguration.java index fe598e3e8d7f..fbd46ac8a138 100644 --- a/java/java-impl/src/com/intellij/javadoc/JavadocConfiguration.java +++ b/java/java-impl/src/com/intellij/javadoc/JavadocConfiguration.java @@ -56,9 +56,7 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; -import java.util.Collection; -import java.util.List; -import java.util.Set; +import java.util.*; /** * @author Eugene Zhuravlev @@ -230,36 +228,7 @@ public class JavadocConfiguration implements ModuleRunProfile, JDOMExternalizabl parameters.addParametersString(OTHER_OPTIONS); - final Set<Module> modules = new HashSet<Module>(); - myGenerationOptions.accept(new PsiRecursiveElementWalkingVisitor() { - @Override - public void visitFile(PsiFile file) { - final Module module = ModuleUtilCore.findModuleForPsiElement(file); - if (module != null) { - modules.add(module); - } - } - }); - final PathsList classPath; - final OrderEnumerator orderEnumerator = ProjectRootManager.getInstance(myProject).orderEntries(modules); - if (jdk.getSdkType() instanceof JavaSdk) { - classPath = orderEnumerator.withoutSdk().withoutModuleSourceEntries().getPathsList(); - } - else { - //libraries are included into jdk - classPath = orderEnumerator.withoutModuleSourceEntries().getPathsList(); - } - final String classPathString = classPath.getPathsString(); - if (classPathString.length() > 0) { - parameters.add("-classpath"); - parameters.add(classPathString); - } - - if (OUTPUT_DIRECTORY != null) { - parameters.add("-d"); - parameters.add(OUTPUT_DIRECTORY.replace('/', File.separatorChar)); - } - + final Set<Module> modules = new LinkedHashSet<Module>(); try { final File sourcePathTempFile = FileUtil.createTempFile("javadoc", "args.txt", true); parameters.add("@" + sourcePathTempFile.getCanonicalPath()); @@ -274,10 +243,10 @@ public class JavadocConfiguration implements ModuleRunProfile, JDOMExternalizabl scopeType == AnalysisScope.MODULES || scopeType == AnalysisScope.PROJECT || scopeType == AnalysisScope.DIRECTORY; - myGenerationOptions.accept(new MyContentIterator(myProject, packages, sources, usePackageNotation)); + myGenerationOptions.accept(new MyContentIterator(myProject, packages, sources, modules, usePackageNotation)); } }; - if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(findRunnable, "Search for sources to generate javadoc in...", false, myProject)) { + if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(findRunnable, "Search for sources to generate javadoc in...", true, myProject)) { return; } if (packages.size() + sources.size() == 0) { @@ -319,6 +288,27 @@ public class JavadocConfiguration implements ModuleRunProfile, JDOMExternalizabl catch (IOException e) { LOGGER.error(e); } + + final PathsList classPath; + final OrderEnumerator orderEnumerator = ProjectRootManager.getInstance(myProject).orderEntries(modules); + if (jdk.getSdkType() instanceof JavaSdk) { + classPath = orderEnumerator.withoutSdk().withoutModuleSourceEntries().getPathsList(); + } + else { + //libraries are included into jdk + classPath = orderEnumerator.withoutModuleSourceEntries().getPathsList(); + } + final String classPathString = classPath.getPathsString(); + if (classPathString.length() > 0) { + parameters.add("-classpath"); + parameters.add(classPathString); + } + + if (OUTPUT_DIRECTORY != null) { + parameters.add("-d"); + parameters.add(OUTPUT_DIRECTORY.replace('/', File.separatorChar)); + } + } @NotNull @@ -343,9 +333,15 @@ public class JavadocConfiguration implements ModuleRunProfile, JDOMExternalizabl private final PsiManager myPsiManager; private final Collection<String> myPackages; private final Collection<String> mySourceFiles; + private final Set<Module> myModules; private final boolean myUsePackageNotation; - public MyContentIterator(Project project, Collection<String> packages, Collection<String> sources, boolean canUsePackageNotation) { + public MyContentIterator(Project project, + Collection<String> packages, + Collection<String> sources, + Set<Module> modules, + boolean canUsePackageNotation) { + myModules = modules; myUsePackageNotation = canUsePackageNotation; myPsiManager = PsiManager.getInstance(project); myPackages = packages; @@ -357,7 +353,10 @@ public class JavadocConfiguration implements ModuleRunProfile, JDOMExternalizabl final VirtualFile fileOrDir = file.getVirtualFile(); if (fileOrDir == null) return; if (!fileOrDir.isInLocalFileSystem()) return; - final Module module = ModuleUtil.findModuleForFile(fileOrDir, myPsiManager.getProject()); + final Module module = ModuleUtilCore.findModuleForFile(fileOrDir, myPsiManager.getProject()); + if (module != null) { + myModules.add(module); + } if (file instanceof PsiJavaFile) { final PsiJavaFile javaFile = (PsiJavaFile)file; final String packageName = javaFile.getPackageName(); diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementMethodDependencyInfo.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/ArrangementEntryDependencyInfo.java index c4cb39290cf1..f5790445b363 100644 --- a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementMethodDependencyInfo.java +++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/ArrangementEntryDependencyInfo.java @@ -24,33 +24,32 @@ import java.util.List; * @author Denis Zhdanov * @since 9/19/12 6:41 PM */ -public class JavaArrangementMethodDependencyInfo { +public class ArrangementEntryDependencyInfo { - @NotNull private final List<JavaArrangementMethodDependencyInfo> myDependentMethods - = new ArrayList<JavaArrangementMethodDependencyInfo>(); + @NotNull private final List<ArrangementEntryDependencyInfo> myDependentEntries = new ArrayList<ArrangementEntryDependencyInfo>(); - @NotNull private final JavaElementArrangementEntry myAnchorMethod; + @NotNull private final JavaElementArrangementEntry myAnchorEntry; - public JavaArrangementMethodDependencyInfo(@NotNull JavaElementArrangementEntry method) { - myAnchorMethod = method; + public ArrangementEntryDependencyInfo(@NotNull JavaElementArrangementEntry entry) { + myAnchorEntry= entry; } - public void addDependentMethodInfo(@NotNull JavaArrangementMethodDependencyInfo info) { - myDependentMethods.add(info); + public void addDependentEntryInfo(@NotNull ArrangementEntryDependencyInfo info) { + myDependentEntries.add(info); } @NotNull - public List<JavaArrangementMethodDependencyInfo> getDependentMethodInfos() { - return myDependentMethods; + public List<ArrangementEntryDependencyInfo> getDependentEntriesInfos() { + return myDependentEntries; } @NotNull - public JavaElementArrangementEntry getAnchorMethod() { - return myAnchorMethod; + public JavaElementArrangementEntry getAnchorEntry() { + return myAnchorEntry; } @Override public String toString() { - return myAnchorMethod.toString(); + return myAnchorEntry.toString(); } } diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementParseInfo.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementParseInfo.java index 3497c235e18e..2796fecea024 100644 --- a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementParseInfo.java +++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementParseInfo.java @@ -17,6 +17,7 @@ package com.intellij.psi.codeStyle.arrangement; import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiField; import com.intellij.psi.PsiMethod; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.ContainerUtilRt; @@ -40,8 +41,8 @@ public class JavaArrangementParseInfo { @NotNull private final Map<Pair<String/* property name */, String/* class name */>, JavaArrangementPropertyInfo> myProperties = new HashMap<Pair<String, String>, JavaArrangementPropertyInfo>(); - @NotNull private final List<JavaArrangementMethodDependencyInfo> myMethodDependencyRoots - = new ArrayList<JavaArrangementMethodDependencyInfo>(); + @NotNull private final List<ArrangementEntryDependencyInfo> myMethodDependencyRoots + = new ArrayList<ArrangementEntryDependencyInfo>(); @NotNull private final Map<PsiMethod /* anchor */, Set<PsiMethod /* dependencies */>> myMethodDependencies = new HashMap<PsiMethod, Set<PsiMethod>>(); @@ -54,10 +55,10 @@ public class JavaArrangementParseInfo { @NotNull private final Set<PsiMethod> myTmpMethodDependencyRoots = new LinkedHashSet<PsiMethod>(); @NotNull private final Set<PsiMethod> myDependentMethods = new HashSet<PsiMethod>(); - - private boolean myRebuildMethodDependencies; + @NotNull private FieldDependenciesManager myFieldDependenciesManager = new FieldDependenciesManager(); + @NotNull public List<JavaElementArrangementEntry> getEntries() { return myEntries; @@ -74,16 +75,16 @@ public class JavaArrangementParseInfo { /** * @return list of method dependency roots, i.e. there is a possible case that particular method - * {@link JavaArrangementMethodDependencyInfo#getDependentMethodInfos() calls another method}, it calls other methods + * {@link ArrangementEntryDependencyInfo#getDependentEntriesInfos() calls another method}, it calls other methods * and so forth */ @NotNull - public List<JavaArrangementMethodDependencyInfo> getMethodDependencyRoots() { + public List<ArrangementEntryDependencyInfo> getMethodDependencyRoots() { if (myRebuildMethodDependencies) { myMethodDependencyRoots.clear(); - Map<PsiMethod, JavaArrangementMethodDependencyInfo> cache = new HashMap<PsiMethod, JavaArrangementMethodDependencyInfo>(); + Map<PsiMethod, ArrangementEntryDependencyInfo> cache = new HashMap<PsiMethod, ArrangementEntryDependencyInfo>(); for (PsiMethod method : myTmpMethodDependencyRoots) { - JavaArrangementMethodDependencyInfo info = buildMethodDependencyInfo(method, cache); + ArrangementEntryDependencyInfo info = buildMethodDependencyInfo(method, cache); if (info != null) { myMethodDependencyRoots.add(info); } @@ -94,20 +95,20 @@ public class JavaArrangementParseInfo { } @Nullable - private JavaArrangementMethodDependencyInfo buildMethodDependencyInfo(@NotNull final PsiMethod method, - @NotNull Map<PsiMethod, JavaArrangementMethodDependencyInfo> cache) + private ArrangementEntryDependencyInfo buildMethodDependencyInfo(@NotNull final PsiMethod method, + @NotNull Map<PsiMethod, ArrangementEntryDependencyInfo> cache) { JavaElementArrangementEntry entry = myMethodEntriesMap.get(method); if (entry == null) { return null; } - JavaArrangementMethodDependencyInfo result = new JavaArrangementMethodDependencyInfo(entry); - Stack<Pair<PsiMethod, JavaArrangementMethodDependencyInfo>> toProcess - = new Stack<Pair<PsiMethod, JavaArrangementMethodDependencyInfo>>(); + ArrangementEntryDependencyInfo result = new ArrangementEntryDependencyInfo(entry); + Stack<Pair<PsiMethod, ArrangementEntryDependencyInfo>> toProcess + = new Stack<Pair<PsiMethod, ArrangementEntryDependencyInfo>>(); toProcess.push(Pair.create(method, result)); Set<PsiMethod> usedMethods = ContainerUtilRt.newHashSet(); while (!toProcess.isEmpty()) { - Pair<PsiMethod, JavaArrangementMethodDependencyInfo> pair = toProcess.pop(); + Pair<PsiMethod, ArrangementEntryDependencyInfo> pair = toProcess.pop(); Set<PsiMethod> dependentMethods = myMethodDependencies.get(pair.first); if (dependentMethods == null) { continue; @@ -122,12 +123,12 @@ public class JavaArrangementParseInfo { if (dependentEntry == null) { continue; } - JavaArrangementMethodDependencyInfo dependentMethodInfo = cache.get(dependentMethod); + ArrangementEntryDependencyInfo dependentMethodInfo = cache.get(dependentMethod); if (dependentMethodInfo == null) { - cache.put(dependentMethod, dependentMethodInfo = new JavaArrangementMethodDependencyInfo(dependentEntry)); + cache.put(dependentMethod, dependentMethodInfo = new ArrangementEntryDependencyInfo(dependentEntry)); } - Pair<PsiMethod, JavaArrangementMethodDependencyInfo> dependentPair = Pair.create(dependentMethod, dependentMethodInfo); - pair.second.addDependentMethodInfo(dependentPair.second); + Pair<PsiMethod, ArrangementEntryDependencyInfo> dependentPair = Pair.create(dependentMethod, dependentMethodInfo); + pair.second.addDependentEntryInfo(dependentPair.second); toProcess.push(dependentPair); } } @@ -156,6 +157,10 @@ public class JavaArrangementParseInfo { myMethodEntriesMap.put(method, entry); } + public void onFieldEntryCreated(@NotNull PsiField field, @NotNull JavaElementArrangementEntry entry) { + myFieldDependenciesManager.registerFieldAndEntry(field, entry); + } + public void onOverriddenMethod(@NotNull PsiMethod baseMethod, @NotNull PsiMethod overridingMethod) { PsiClass clazz = baseMethod.getContainingClass(); if (clazz == null) { @@ -203,23 +208,67 @@ public class JavaArrangementParseInfo { /** * Is expected to be called when new method dependency is detected. Here given <code>'base method'</code> calls * <code>'dependent method'</code>. - * - * @param baseMethod method which calls another method - * @param dependentMethod method being called */ - public void registerDependency(@NotNull PsiMethod baseMethod, @NotNull PsiMethod dependentMethod) { - myTmpMethodDependencyRoots.remove(dependentMethod); - if (!myDependentMethods.contains(baseMethod)) { - myTmpMethodDependencyRoots.add(baseMethod); + public void registerMethodCallDependency(@NotNull PsiMethod caller, @NotNull PsiMethod callee) { + myTmpMethodDependencyRoots.remove(callee); + if (!myDependentMethods.contains(caller)) { + myTmpMethodDependencyRoots.add(caller); } - myDependentMethods.add(dependentMethod); - Set<PsiMethod> methods = myMethodDependencies.get(baseMethod); + myDependentMethods.add(callee); + Set<PsiMethod> methods = myMethodDependencies.get(caller); if (methods == null) { - myMethodDependencies.put(baseMethod, methods = new LinkedHashSet<PsiMethod>()); + myMethodDependencies.put(caller, methods = new LinkedHashSet<PsiMethod>()); } - if (!methods.contains(dependentMethod)) { - methods.add(dependentMethod); + if (!methods.contains(callee)) { + methods.add(callee); } myRebuildMethodDependencies = true; } -} + + public void registerFieldInitializationDependency(@NotNull PsiField fieldToInitialize, @NotNull PsiField usedInInitialization) { + myFieldDependenciesManager.registerInitializationDependency(fieldToInitialize, usedInInitialization); + } + + @NotNull + public List<ArrangementEntryDependencyInfo> getFieldDependencyRoots() { + return myFieldDependenciesManager.getRoots(); + } + + private static class FieldDependenciesManager { + private final Map<PsiField, Set<PsiField>> myFieldDependencies = ContainerUtil.newHashMap(); + private final Map<PsiField, ArrangementEntryDependencyInfo> myFieldInfosMap = ContainerUtil.newHashMap(); + + + public void registerFieldAndEntry(@NotNull PsiField field, @NotNull JavaElementArrangementEntry entry) { + myFieldInfosMap.put(field, new ArrangementEntryDependencyInfo(entry)); + } + + public void registerInitializationDependency(@NotNull PsiField fieldToInitialize, @NotNull PsiField usedInInitialization) { + Set<PsiField> fields = myFieldDependencies.get(fieldToInitialize); + if (fields == null) { + fields = new HashSet<PsiField>(); + myFieldDependencies.put(fieldToInitialize, fields); + } + fields.add(usedInInitialization); + } + + @NotNull + public List<ArrangementEntryDependencyInfo> getRoots() { + List<ArrangementEntryDependencyInfo> list = ContainerUtil.newArrayList(); + + for (Map.Entry<PsiField, Set<PsiField>> entry : myFieldDependencies.entrySet()) { + ArrangementEntryDependencyInfo currentInfo = myFieldInfosMap.get(entry.getKey()); + + for (PsiField usedInInitialization : entry.getValue()) { + ArrangementEntryDependencyInfo fieldInfo = myFieldInfosMap.get(usedInInitialization); + if (fieldInfo != null) + currentInfo.addDependentEntryInfo(fieldInfo); + } + + list.add(currentInfo); + } + + return list; + } + } +}
\ No newline at end of file diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java index a5fd586e6b31..826ad21e3ffe 100644 --- a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java +++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java @@ -17,7 +17,6 @@ package com.intellij.psi.codeStyle.arrangement; import com.intellij.openapi.editor.Document; import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.arrangement.std.ArrangementSettingsToken; import com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens; @@ -29,10 +28,7 @@ import com.intellij.util.containers.Stack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; +import java.util.*; import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.EntryType.*; import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Modifier.*; @@ -163,10 +159,40 @@ public class JavaArrangementVisitor extends JavaElementVisitor { break; } } + JavaElementArrangementEntry entry = createNewEntry(field, range, FIELD, field.getName(), true); - processEntry(entry, field, field.getInitializer()); + if (entry == null) + return; + + PsiExpression fieldInitializer = field.getInitializer(); + processEntry(entry, field, fieldInitializer); + myInfo.onFieldEntryCreated(field, entry); + + if (fieldInitializer != null) { + List<PsiField> referencedFields = getReferencedFields(fieldInitializer); + for (PsiField referencedField : referencedFields) { + myInfo.registerFieldInitializationDependency(field, referencedField); + } + } } + @NotNull + private List<PsiField> getReferencedFields(@NotNull PsiExpression expression) { + final List<PsiField> referencedElements = new ArrayList<PsiField>(); + expression.accept(new JavaRecursiveElementVisitor() { + @Override + public void visitReferenceExpression(PsiReferenceExpression expression) { + PsiElement ref = expression.resolve(); + if (ref instanceof PsiField) { + referencedElements.add((PsiField)ref); + } + } + }); + + return referencedElements; + } + + @Nullable private static PsiElement getPreviousNonWsComment(@Nullable PsiElement element, int minOffset) { if (element == null) { @@ -443,7 +469,7 @@ public class JavaArrangementVisitor extends JavaElementVisitor { assert myBaseMethod != null; PsiMethod m = (PsiMethod)e; if (m.getContainingClass() == myBaseMethod.getContainingClass()) { - myInfo.registerDependency(myBaseMethod, m); + myInfo.registerMethodCallDependency(myBaseMethod, m); } } diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java index 001745c2dc10..cc35e7d75e70 100644 --- a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java +++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java @@ -121,12 +121,12 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>, private static void setupUtilityMethods(@NotNull JavaArrangementParseInfo info, @NotNull ArrangementSettingsToken orderType) { if (DEPTH_FIRST.equals(orderType)) { - for (JavaArrangementMethodDependencyInfo rootInfo : info.getMethodDependencyRoots()) { + for (ArrangementEntryDependencyInfo rootInfo : info.getMethodDependencyRoots()) { setupDepthFirstDependency(rootInfo); } } else if (BREADTH_FIRST.equals(orderType)) { - for (JavaArrangementMethodDependencyInfo rootInfo : info.getMethodDependencyRoots()) { + for (ArrangementEntryDependencyInfo rootInfo : info.getMethodDependencyRoots()) { setupBreadthFirstDependency(rootInfo); } } @@ -135,25 +135,25 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>, } } - private static void setupDepthFirstDependency(@NotNull JavaArrangementMethodDependencyInfo info) { - for (JavaArrangementMethodDependencyInfo dependencyInfo : info.getDependentMethodInfos()) { + private static void setupDepthFirstDependency(@NotNull ArrangementEntryDependencyInfo info) { + for (ArrangementEntryDependencyInfo dependencyInfo : info.getDependentEntriesInfos()) { setupDepthFirstDependency(dependencyInfo); - JavaElementArrangementEntry dependentEntry = dependencyInfo.getAnchorMethod(); + JavaElementArrangementEntry dependentEntry = dependencyInfo.getAnchorEntry(); if (dependentEntry.getDependencies() == null) { - dependentEntry.addDependency(info.getAnchorMethod()); + dependentEntry.addDependency(info.getAnchorEntry()); } } } - private static void setupBreadthFirstDependency(@NotNull JavaArrangementMethodDependencyInfo info) { - Deque<JavaArrangementMethodDependencyInfo> toProcess = new ArrayDeque<JavaArrangementMethodDependencyInfo>(); + private static void setupBreadthFirstDependency(@NotNull ArrangementEntryDependencyInfo info) { + Deque<ArrangementEntryDependencyInfo> toProcess = new ArrayDeque<ArrangementEntryDependencyInfo>(); toProcess.add(info); while (!toProcess.isEmpty()) { - JavaArrangementMethodDependencyInfo current = toProcess.removeFirst(); - for (JavaArrangementMethodDependencyInfo dependencyInfo : current.getDependentMethodInfos()) { - JavaElementArrangementEntry dependencyMethod = dependencyInfo.getAnchorMethod(); + ArrangementEntryDependencyInfo current = toProcess.removeFirst(); + for (ArrangementEntryDependencyInfo dependencyInfo : current.getDependentEntriesInfos()) { + JavaElementArrangementEntry dependencyMethod = dependencyInfo.getAnchorEntry(); if (dependencyMethod.getDependencies() == null) { - dependencyMethod.addDependency(current.getAnchorMethod()); + dependencyMethod.addDependency(current.getAnchorEntry()); } toProcess.addLast(dependencyInfo); } @@ -216,9 +216,21 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>, } } } + setupFieldInitializationDependencies(parseInfo.getFieldDependencyRoots()); return parseInfo.getEntries(); } + + public void setupFieldInitializationDependencies(@NotNull List<ArrangementEntryDependencyInfo> list) { + for (ArrangementEntryDependencyInfo info : list) { + JavaElementArrangementEntry anchorField = info.getAnchorEntry(); + for (ArrangementEntryDependencyInfo fieldUsedInInitialization : info.getDependentEntriesInfos()) { + anchorField.addDependency(fieldUsedInInitialization.getAnchorEntry()); + } + } + } + + @Override public int getBlankLines(@NotNull CodeStyleSettings settings, @Nullable JavaElementArrangementEntry parent, diff --git a/java/java-impl/src/com/intellij/psi/impl/JavaDirectoryIconProvider.java b/java/java-impl/src/com/intellij/psi/impl/JavaDirectoryIconProvider.java index 8efae1602e04..795e66e01ed4 100644 --- a/java/java-impl/src/com/intellij/psi/impl/JavaDirectoryIconProvider.java +++ b/java/java-impl/src/com/intellij/psi/impl/JavaDirectoryIconProvider.java @@ -23,7 +23,7 @@ import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.roots.SourceFolder; -import com.intellij.openapi.roots.ui.configuration.ModuleSourceRootEditHandler; +import com.intellij.openapi.roots.ui.configuration.SourceRootPresentation; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.JavaDirectoryService; @@ -63,7 +63,7 @@ public class JavaDirectoryIconProvider extends IconProvider implements DumbAware } } else if (sourceFolder != null) { - symbolIcon = ModuleSourceRootEditHandler.getEditHandler(sourceFolder.getRootType()).getRootIcon(); + symbolIcon = SourceRootPresentation.getSourceRootIcon(sourceFolder); } else if (JavaDirectoryService.getInstance().getPackage(psiDirectory) != null) { symbolIcon = PlatformIcons.PACKAGE_ICON; diff --git a/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java b/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java index 6026d8f33b76..ee207fb89fc7 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java @@ -26,6 +26,7 @@ import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.changeSignature.ChangeSignatureUtil; +import com.intellij.refactoring.listeners.RefactoringEventData; import com.intellij.refactoring.util.RefactoringUIUtil; import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageViewDescriptor; @@ -33,6 +34,7 @@ import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -117,6 +119,28 @@ public class ChangeClassSignatureProcessor extends BaseRefactoringProcessor { } } + @Nullable + @Override + protected String getRefactoringId() { + return "refactoring.changeClassSignature"; + } + + @Nullable + @Override + protected RefactoringEventData getBeforeData() { + RefactoringEventData data = new RefactoringEventData(); + data.addElement(myClass); + return data; + } + + @Nullable + @Override + protected RefactoringEventData getAfterData(UsageInfo[] usages) { + RefactoringEventData data = new RefactoringEventData(); + data.addElement(myClass); + return data; + } + private void doRefactoring(UsageInfo[] usages) throws IncorrectOperationException { final PsiTypeParameter[] typeParameters = myClass.getTypeParameters(); final boolean[] toRemoveParms = detectRemovedParameters(typeParameters); diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java index 1f9ec4d9b894..17cef58390c6 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java index c3a8d7279c2c..5804445d7141 100644 --- a/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java @@ -32,6 +32,7 @@ import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.listeners.RefactoringEventData; import com.intellij.refactoring.move.moveInstanceMethod.MoveInstanceMethodViewDescriptor; import com.intellij.refactoring.util.*; import com.intellij.usageView.UsageInfo; @@ -132,6 +133,28 @@ public class ConvertToInstanceMethodProcessor extends BaseRefactoringProcessor { } + @Nullable + @Override + protected String getRefactoringId() { + return "refactoring.makeInstance"; + } + + @Nullable + @Override + protected RefactoringEventData getBeforeData() { + RefactoringEventData data = new RefactoringEventData(); + data.addElements(new PsiElement[]{myMethod, myTargetClass}); + return data; + } + + @Nullable + @Override + protected RefactoringEventData getAfterData(UsageInfo[] usages) { + RefactoringEventData data = new RefactoringEventData(); + data.addElement(myTargetClass); + return data; + } + protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) { UsageInfo[] usagesIn = refUsages.get(); MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>(); 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 986f98b5fc39..93d9f089f2c1 100644 --- a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java @@ -1,4 +1,3 @@ - /* * Copyright 2000-2013 JetBrains s.r.o. * @@ -27,6 +26,7 @@ import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.*; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.listeners.RefactoringEventData; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.RefactoringUIUtil; @@ -39,6 +39,7 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -72,6 +73,39 @@ public class EncapsulateFieldsProcessor extends BaseRefactoringProcessor { } } + @Nullable + @Override + protected String getRefactoringId() { + return "refactoring.encapsulateFields"; + } + + @Nullable + @Override + protected RefactoringEventData getBeforeData() { + RefactoringEventData data = new RefactoringEventData(); + final List<PsiElement> fields = new ArrayList<PsiElement>(); + for (FieldDescriptor fieldDescriptor : myFieldDescriptors) { + fields.add(fieldDescriptor.getField()); + } + data.addElements(fields); + return data; + } + + @Nullable + @Override + protected RefactoringEventData getAfterData(UsageInfo[] usages) { + RefactoringEventData data = new RefactoringEventData(); + List<PsiElement> elements = new ArrayList<PsiElement>(); + if (myNameToGetter != null) { + elements.addAll(myNameToGetter.values()); + } + if (myNameToSetter != null) { + elements.addAll(myNameToSetter.values()); + } + data.addElements(elements); + return data; + } + @NotNull protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { FieldDescriptor[] fields = new FieldDescriptor[myFieldDescriptors.length]; diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java index f3f7c854eb65..659ebfb288ad 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java @@ -45,6 +45,8 @@ import com.intellij.refactoring.IntroduceTargetChooser; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.introduceVariable.IntroduceVariableBase; +import com.intellij.refactoring.listeners.RefactoringEventData; +import com.intellij.refactoring.listeners.RefactoringEventListener; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.refactoring.util.duplicates.DuplicatesImpl; @@ -151,7 +153,14 @@ public class ExtractMethodHandler implements RefactoringActionHandler { PostprocessReformattingAspect.getInstance(project).postponeFormattingInside(new Runnable() { public void run() { try { + project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC) + .refactoringStarted("refactoring.extract.method", new RefactoringEventData()); + processor.doRefactoring(); + + final RefactoringEventData data = new RefactoringEventData(); + data.addElement(processor.getExtractedMethod()); + project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringDone("refactoring.extract.method", data); } catch (IncorrectOperationException e) { LOG.error(e); diff --git a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseProcessor.java index 0d608e736bcc..aae2d488af46 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseProcessor.java @@ -25,6 +25,7 @@ import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.MethodSignatureUtil; import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.listeners.RefactoringEventData; import com.intellij.refactoring.turnRefsToSuper.TurnRefsToSuperProcessorBase; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.RefactoringUIUtil; @@ -33,11 +34,14 @@ import com.intellij.refactoring.util.classMembers.MemberInfo; import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageViewDescriptor; import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collection; +import java.util.List; /** * @author dsl @@ -102,6 +106,34 @@ public abstract class ExtractSuperBaseProcessor extends TurnRefsToSuperProcessor return false; } + @Nullable + @Override + protected String getRefactoringId() { + return "refactoring.extractSuper"; + } + + @Nullable + @Override + protected RefactoringEventData getBeforeData() { + RefactoringEventData data = new RefactoringEventData(); + data.addElement(myClass); + data.addMembers(myMemberInfos, new Function<MemberInfo, PsiElement>() { + @Override + public PsiElement fun(MemberInfo info) { + return info.getMember(); + } + }); + return data; + } + + @Nullable + @Override + protected RefactoringEventData getAfterData(UsageInfo[] usages) { + RefactoringEventData data = new RefactoringEventData(); + data.addElement(myClass); + return data; + } + @NotNull protected UsageInfo[] findUsages() { PsiReference[] refs = ReferencesSearch.search(myClass, GlobalSearchScope.projectScope(myProject), false).toArray(new PsiReference[0]); diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java index 508a32fc678f..f6ef8ff88889 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java @@ -27,6 +27,8 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.listeners.RefactoringEventData; +import com.intellij.refactoring.listeners.RefactoringEventListener; import com.intellij.refactoring.rename.NonCodeUsageInfoFactory; import com.intellij.refactoring.util.*; import com.intellij.usageView.UsageInfo; @@ -34,6 +36,7 @@ import com.intellij.usageView.UsageViewDescriptor; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -168,6 +171,20 @@ public class InlineConstantFieldProcessor extends BaseRefactoringProcessor { } } + @Nullable + @Override + protected RefactoringEventData getBeforeData() { + RefactoringEventData data = new RefactoringEventData(); + data.addElement(myField); + return data; + } + + @Nullable + @Override + protected String getRefactoringId() { + return "refactoring.inline.field"; + } + private void inlineExpressionUsage(PsiExpression expr, PsiExpression initializer1) throws IncorrectOperationException { if (myField.isWritable()) { diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java index 729380654dfb..aaece25db719 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java @@ -47,6 +47,8 @@ import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.introduceParameter.Util; +import com.intellij.refactoring.listeners.RefactoringEventData; +import com.intellij.refactoring.listeners.RefactoringEventListener; import com.intellij.refactoring.rename.NonCodeUsageInfoFactory; import com.intellij.refactoring.rename.RenameJavaVariableProcessor; import com.intellij.refactoring.util.*; @@ -389,6 +391,20 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor { } } + @Nullable + @Override + protected String getRefactoringId() { + return "refactoring.inline.method"; + } + + @Nullable + @Override + protected RefactoringEventData getBeforeData() { + final RefactoringEventData data = new RefactoringEventData(); + data.addElement(myMethod); + return data; + } + private void doRefactoring(UsageInfo[] usages) { try { if (myInlineThisOnly) { diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterExpressionProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterExpressionProcessor.java index b7caffed9003..81c5b6985ea0 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterExpressionProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterExpressionProcessor.java @@ -50,7 +50,7 @@ public class InlineParameterExpressionProcessor extends BaseRefactoringProcessor private final PsiParameter myParameter; private PsiExpression myInitializer; private final boolean mySameClass; - private final PsiMethod myCallingMethod; + private final PsiCodeBlock myCallingBlock; private final boolean myCreateLocal; public InlineParameterExpressionProcessor(final PsiCallExpression methodCall, @@ -67,7 +67,7 @@ public class InlineParameterExpressionProcessor extends BaseRefactoringProcessor PsiClass callingClass = PsiTreeUtil.getParentOfType(methodCall, PsiClass.class); mySameClass = (callingClass == myMethod.getContainingClass()); - myCallingMethod = PsiTreeUtil.getParentOfType(myMethodCall, PsiMethod.class); + myCallingBlock = PsiTreeUtil.getTopmostParentOfType(myMethodCall, PsiCodeBlock.class); } @Override @@ -110,7 +110,7 @@ public class InlineParameterExpressionProcessor extends BaseRefactoringProcessor final PsiElement element = expression.resolve(); if (element instanceof PsiLocalVariable) { final PsiLocalVariable localVariable = (PsiLocalVariable)element; - final PsiElement[] elements = DefUseUtil.getDefs(myCallingMethod.getBody(), localVariable, expression); + final PsiElement[] elements = DefUseUtil.getDefs(myCallingBlock, localVariable, expression); if (elements.length == 1) { PsiExpression localInitializer = null; if (elements[0] instanceof PsiLocalVariable) { diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java index 58d4d1eb282d..e5c94905546f 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java @@ -33,6 +33,8 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.listeners.RefactoringEventData; +import com.intellij.refactoring.listeners.RefactoringEventListener; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.InlineUtil; import com.intellij.refactoring.util.RefactoringMessageDialog; @@ -47,6 +49,7 @@ import java.util.*; public class InlineParameterHandler extends JavaInlineActionHandler { private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.inline.InlineParameterHandler"); public static final String REFACTORING_NAME = RefactoringBundle.message("inline.parameter.refactoring"); + public static final String REFACTORING_ID = "refactoring.inline.parameter"; public boolean canInlineElement(PsiElement element) { if (element instanceof PsiParameter) { @@ -212,8 +215,13 @@ public class InlineParameterHandler extends JavaInlineActionHandler { } } + final RefactoringEventData data = new RefactoringEventData(); + data.addElement(psiElement.copy()); + project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringStarted(REFACTORING_ID, data); SameParameterValueInspection.InlineParameterValueFix.inlineSameParameterValue(method, psiParameter, constantExpression); + + project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringDone(REFACTORING_ID, null); } @Nullable diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineStaticImportHandler.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineStaticImportHandler.java index 6abc17b97152..41173c93c870 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineStaticImportHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineStaticImportHandler.java @@ -23,6 +23,8 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiImportStaticStatement; import com.intellij.psi.PsiJavaCodeReferenceElement; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.listeners.RefactoringEventData; +import com.intellij.refactoring.listeners.RefactoringEventListener; import java.util.List; @@ -36,6 +38,7 @@ import static com.intellij.psi.util.ImportsUtil.replaceAllAndDeleteImport; public class InlineStaticImportHandler extends JavaInlineActionHandler { private static final String REFACTORING_NAME = "Expand static import"; + public static final String REFACTORING_ID = "refactoring.inline.import"; @Override public boolean canInlineElement(PsiElement element) { @@ -48,11 +51,18 @@ public class InlineStaticImportHandler extends JavaInlineActionHandler { final PsiImportStaticStatement staticStatement = PsiTreeUtil.getParentOfType(element, PsiImportStaticStatement.class); final List<PsiJavaCodeReferenceElement> referenceElements = collectReferencesThrough(element.getContainingFile(), null, staticStatement); + + RefactoringEventData data = new RefactoringEventData(); + data.addElement(element); + project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringStarted(REFACTORING_ID, data); + + new WriteCommandAction(project, REFACTORING_NAME){ @Override protected void run(Result result) throws Throwable { replaceAllAndDeleteImport(referenceElements, null, staticStatement); } }.execute(); + project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringDone(REFACTORING_ID, null); } } diff --git a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java index ab340a596947..ced576887801 100644 --- a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java @@ -30,6 +30,7 @@ import com.intellij.psi.util.PsiTypesUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.inlineSuperClass.usageInfo.*; +import com.intellij.refactoring.listeners.RefactoringEventData; import com.intellij.refactoring.memberPushDown.PushDownConflicts; import com.intellij.refactoring.memberPushDown.PushDownProcessor; import com.intellij.refactoring.util.*; @@ -318,6 +319,29 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori }.run(); } + @Nullable + @Override + protected RefactoringEventData getBeforeData() { + final RefactoringEventData data = new RefactoringEventData(); + data.addElement(mySuperClass); + data.addElements(myTargetClasses); + return data; + } + + @Nullable + @Override + protected RefactoringEventData getAfterData(UsageInfo[] usages) { + final RefactoringEventData data = new RefactoringEventData(); + data.addElements(myTargetClasses); + return data; + } + + @Nullable + @Override + protected String getRefactoringId() { + return "refactoring.inline.class"; + } + private void replaceInnerTypeUsages() { final JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject); final PsiElementFactory elementFactory = facade.getElementFactory(); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java index ba3ba8a2c7bd..076734e90a7f 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java @@ -41,6 +41,7 @@ import com.intellij.refactoring.IntroduceParameterRefactoring; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor; import com.intellij.refactoring.introduceVariable.IntroduceVariableBase; +import com.intellij.refactoring.listeners.RefactoringEventData; import com.intellij.refactoring.util.*; import com.intellij.refactoring.util.occurrences.ExpressionOccurrenceManager; import com.intellij.refactoring.util.occurrences.LocalVariableOccurrenceManager; @@ -336,6 +337,20 @@ public class IntroduceParameterProcessor extends BaseRefactoringProcessor implem } } + @Nullable + @Override + protected String getRefactoringId() { + return "refactoring.introduceParameter"; + } + + @Nullable + @Override + protected RefactoringEventData getBeforeData() { + RefactoringEventData data = new RefactoringEventData(); + data.addElements(new PsiElement[] {myLocalVariable, myExpressionToSearch}); + return data; + } + protected void performRefactoring(UsageInfo[] usages) { try { PsiElementFactory factory = JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory(); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java index 4ec3a1397111..53162cd09b30 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -37,10 +37,7 @@ import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.Pass; -import com.intellij.openapi.util.Ref; -import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.WindowManager; @@ -414,6 +411,12 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { final PsiExpression toBeExpression = createReplacement(fakeInitializer, project, prefix, suffix, parent, rangeMarker, refIdx); toBeExpression.accept(errorsVisitor); if (hasErrors[0]) return null; + if (literalExpression != null) { + PsiType type = toBeExpression.getType(); + if (type != null && !type.equals(literalExpression.getType())) { + return null; + } + } final PsiReferenceExpression refExpr = PsiTreeUtil.getParentOfType(toBeExpression.findElementAt(refIdx[0]), PsiReferenceExpression.class); if (refExpr == null) return null; @@ -692,6 +695,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { while (true) { if (containerParent instanceof PsiFile) break; if (containerParent instanceof PsiMethod) break; + if (containerParent instanceof PsiLambdaExpression) break; if (!skipForStatement && containerParent instanceof PsiForStatement) break; containerParent = containerParent.getParent(); if (containerParent instanceof PsiCodeBlock) { diff --git a/java/java-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanHandler.java b/java/java-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanHandler.java index be8cab8538bf..df8b69cb7064 100644 --- a/java/java-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanHandler.java @@ -68,7 +68,7 @@ public class InvertBooleanHandler implements RefactoringActionHandler { new InvertBooleanDialog(var).show(); } - public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, @NotNull DataContext dataContext) { + public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) { if (elements.length == 1) { if (elements[0] instanceof PsiMethod) { invoke((PsiMethod)elements[0], project, null); diff --git a/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeMethodOrClassStaticProcessor.java b/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeMethodOrClassStaticProcessor.java index 2e6467b3a06a..758e102cccc3 100644 --- a/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeMethodOrClassStaticProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeMethodOrClassStaticProcessor.java @@ -36,6 +36,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.listeners.RefactoringEventData; import com.intellij.refactoring.ui.ConflictsDialog; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.ConflictsUtil; @@ -48,6 +49,7 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.HashSet; @@ -72,6 +74,28 @@ public abstract class MakeMethodOrClassStaticProcessor<T extends PsiTypeParamete return new MakeMethodOrClassStaticViewDescriptor(myMember); } + @Nullable + @Override + protected String getRefactoringId() { + return "refactoring.makeStatic"; + } + + @Nullable + @Override + protected RefactoringEventData getBeforeData() { + RefactoringEventData data = new RefactoringEventData(); + data.addElement(myMember); + return data; + } + + @Nullable + @Override + protected RefactoringEventData getAfterData(UsageInfo[] usages) { + RefactoringEventData data = new RefactoringEventData(); + data.addElement(myMember); + return data; + } + protected final boolean preprocessUsages(final Ref<UsageInfo[]> refUsages) { UsageInfo[] usagesIn = refUsages.get(); if (myPrepareSuccessfulSwingThreadCallback != null) { diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpProcessor.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpProcessor.java index 310d5919cf71..5e6ac953d789 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpProcessor.java @@ -42,6 +42,7 @@ import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.classMembers.MemberInfoBase; import com.intellij.refactoring.listeners.JavaRefactoringListenerManager; +import com.intellij.refactoring.listeners.RefactoringEventData; import com.intellij.refactoring.listeners.impl.JavaRefactoringListenerManagerImpl; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.RefactoringUIUtil; @@ -49,10 +50,12 @@ import com.intellij.refactoring.util.classMembers.MemberInfo; import com.intellij.refactoring.util.duplicates.MethodDuplicatesHandler; import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; import com.intellij.util.Query; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -94,6 +97,26 @@ public class PullUpProcessor extends BaseRefactoringProcessor implements PullUpD return result.isEmpty() ? UsageInfo.EMPTY_ARRAY : result.toArray(new UsageInfo[result.size()]); } + @Nullable + @Override + protected String getRefactoringId() { + return "refactoring.pullUp"; + } + + @Nullable + @Override + protected RefactoringEventData getBeforeData() { + RefactoringEventData data = new RefactoringEventData(); + data.addElement(mySourceClass); + data.addMembers(myMembersToMove, new Function<MemberInfo, PsiElement>() { + @Override + public PsiElement fun(MemberInfo info) { + return info.getMember(); + } + }); + return data; + } + protected void performRefactoring(UsageInfo[] usages) { moveMembersToBase(); moveFieldInitializations(); diff --git a/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownProcessor.java b/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownProcessor.java index a6cecc764e97..31139257d5d0 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownProcessor.java @@ -38,15 +38,18 @@ import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.listeners.JavaRefactoringListenerManager; +import com.intellij.refactoring.listeners.RefactoringEventData; import com.intellij.refactoring.listeners.impl.JavaRefactoringListenerManagerImpl; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.refactoring.util.classMembers.MemberInfo; import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -77,6 +80,41 @@ public class PushDownProcessor extends BaseRefactoringProcessor { return new PushDownUsageViewDescriptor(myClass); } + @Nullable + @Override + protected String getRefactoringId() { + return "refactoring.psuDown"; + } + + @Nullable + @Override + protected RefactoringEventData getBeforeData() { + RefactoringEventData data = new RefactoringEventData(); + data.addElement(myClass); + data.addMembers(myMemberInfos, new Function<MemberInfo, PsiElement>() { + @Override + public PsiElement fun(MemberInfo info) { + return info.getMember(); + } + }); + return data; + } + + @Nullable + @Override + protected RefactoringEventData getAfterData(UsageInfo[] usages) { + final List<PsiElement> elements = new ArrayList<PsiElement>(); + for (UsageInfo usage : usages) { + PsiElement element = usage.getElement(); + if (element instanceof PsiClass) { + elements.add(element); + } + } + RefactoringEventData data = new RefactoringEventData(); + data.addElements(elements); + return data; + } + @NotNull protected UsageInfo[] findUsages() { final PsiClass[] inheritors = ClassInheritorsSearch.search(myClass, false).toArray(PsiClass.EMPTY_ARRAY); 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 5a086c7a7f2f..f398dfdd115a 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 @@ -37,6 +37,7 @@ import com.intellij.refactoring.MoveDestination; import com.intellij.refactoring.PackageWrapper; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.refactoring.listeners.RefactoringEventData; import com.intellij.refactoring.move.MoveCallback; import com.intellij.refactoring.move.MoveClassesOrPackagesCallback; import com.intellij.refactoring.move.MoveMultipleElementsViewDescriptor; @@ -217,7 +218,28 @@ public class MoveClassesOrPackagesProcessor extends BaseRefactoringProcessor { } } + @Nullable + @Override + protected String getRefactoringId() { + return "refactoring.move"; + } + @Nullable + @Override + protected RefactoringEventData getBeforeData() { + RefactoringEventData data = new RefactoringEventData(); + data.addElements(myElementsToMove); + return data; + } + + @Nullable + @Override + protected RefactoringEventData getAfterData(UsageInfo[] usages) { + RefactoringEventData data = new RefactoringEventData(); + data.addElements(myTargetPackage.getDirectories()); + data.addElement(JavaPsiFacade.getInstance(myProject).findPackage(myTargetPackage.getQualifiedName())); + return data; + } protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) { final UsageInfo[] usages = refUsages.get(); diff --git a/java/java-impl/src/com/intellij/refactoring/util/RefactoringConflictsUtil.java b/java/java-impl/src/com/intellij/refactoring/util/RefactoringConflictsUtil.java index 2ec39e07542c..aece13de0764 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/RefactoringConflictsUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringConflictsUtil.java @@ -149,9 +149,10 @@ public class RefactoringConflictsUtil { PsiReferenceExpression refExpr = (PsiReferenceExpression)scope; PsiElement refElement = refExpr.resolve(); if (refElement instanceof PsiMember) { - if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, moving, targetClass, false)) { - PsiExpression qualifier = refExpr.getQualifierExpression(); - PsiClass accessClass = (PsiClass)(qualifier != null ? PsiUtil.getAccessObjectClass(qualifier).getElement() : null); + PsiExpression qualifier = refExpr.getQualifierExpression(); + PsiClass accessClass = (PsiClass)(qualifier != null ? PsiUtil.getAccessObjectClass(qualifier).getElement() : null); + if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, moving, targetClass, false) && + (accessClass == null || !RefactoringHierarchyUtil.willBeInTargetClass(accessClass, moving, targetClass, false))) { checkAccessibility((PsiMember)refElement, context, accessClass, member, conflicts); } } diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java index 6d8f91b7e289..4851504f5b76 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -455,7 +455,12 @@ public class LambdaUtil { if (!tryToSubstitute) return cachedType; } - final PsiElement gParent = expressionList.getParent(); + PsiElement gParent = expressionList.getParent(); + + if (gParent instanceof PsiAnonymousClass) { + gParent = gParent.getParent(); + } + if (gParent instanceof PsiCall) { final PsiCall contextCall = (PsiCall)gParent; final JavaResolveResult resolveResult = contextCall.resolveMethodGenerics(); diff --git a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java index ad92cfebb62d..96930ebe4f97 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java @@ -87,6 +87,7 @@ public class PsiMethodReferenceUtil { myReferenceTypeQualified = referenceTypeQualified; } + @Nullable public PsiClass getContainingClass() { return myContainingClass; } diff --git a/java/java-psi-api/src/com/intellij/psi/PsiSubstitutor.java b/java/java-psi-api/src/com/intellij/psi/PsiSubstitutor.java index c60ece83b8a7..ddc301e0eabe 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiSubstitutor.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiSubstitutor.java @@ -29,12 +29,7 @@ import java.util.Map; * @see com.intellij.psi.JavaResolveResult#getSubstitutor() */ public interface PsiSubstitutor { - Key<PsiSubstitutor> KEY = new KeyWithDefaultValue<PsiSubstitutor>("SUBSTITUTOR") { - @Override - public PsiSubstitutor getDefaultValue() { - return EMPTY; - } - }; + Key<PsiSubstitutor> KEY = KeyWithDefaultValue.<PsiSubstitutor>create("SUBSTITUTOR", EmptySubstitutor.getInstance()); /** * Empty, or natural, substitutor. For any type parameter <code>T</code>, diff --git a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java index c6a8d713e1c2..0851f2640bc6 100644 --- a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java +++ b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java @@ -111,22 +111,24 @@ public class MethodCandidateInfo extends CandidateInfo{ } else { final PsiSubstitutor substitutor = getSubstitutor(); - level = ourOverloadGuard.doPreventingRecursion(myArgumentList, false, new Computable<Integer>() { + Integer boxedLevel = ourOverloadGuard.doPreventingRecursion(myArgumentList, false, new Computable<Integer>() { @Override public Integer compute() { return PsiUtil.getApplicabilityLevel(getElement(), substitutor, myArgumentTypes, myLanguageLevel); } }); + level = boxedLevel != null ? boxedLevel : getApplicabilityLevel(); } if (level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable()) level = ApplicabilityLevel.NOT_APPLICABLE; return level; } - return ourOverloadGuard.doPreventingRecursion(myArgumentList, false, new Computable<Integer>() { + Integer boxedLevel = ourOverloadGuard.doPreventingRecursion(myArgumentList, false, new Computable<Integer>() { @Override public Integer compute() { return getApplicabilityLevelInner(); } }); + return boxedLevel != null ? boxedLevel : getApplicabilityLevel(); } public PsiSubstitutor getSiteSubstitutor() { diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java index f64f207eab15..c448926a5874 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java @@ -17,6 +17,7 @@ package com.intellij.psi.util; import com.intellij.lang.ASTNode; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; @@ -215,4 +216,16 @@ public class PsiTypesUtil { } return null; } + + public static boolean compareTypes(PsiType leftType, PsiType rightType, boolean ignoreEllipsis) { + if (ignoreEllipsis) { + if (leftType instanceof PsiEllipsisType) { + leftType = ((PsiEllipsisType)leftType).toArrayType(); + } + if (rightType instanceof PsiEllipsisType) { + rightType = ((PsiEllipsisType)rightType).toArrayType(); + } + } + return Comparing.equal(leftType, rightType); + } } diff --git a/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java b/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java index 7bb65a15234d..6df6f2a5cfec 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java @@ -17,10 +17,12 @@ package com.intellij.psi.util; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Ref; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.tree.IElementType; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; @@ -465,9 +467,11 @@ public class RedundantCastUtil { final PsiType expectedTypeByParent = PsiTypesUtil.getExpectedTypeByParent(typeCast); if (expectedTypeByParent != null) { try { + final Project project = operand.getProject(); + final String uniqueVariableName = JavaCodeStyleManager.getInstance(project).suggestUniqueVariableName("l", parent, false); final PsiDeclarationStatement declarationStatement = - (PsiDeclarationStatement)JavaPsiFacade.getElementFactory(operand.getProject()).createStatementFromText( - expectedTypeByParent.getCanonicalText() + " l = " + operand.getText() + ";", parent); + (PsiDeclarationStatement)JavaPsiFacade.getElementFactory(project).createStatementFromText( + expectedTypeByParent.getCanonicalText() + " " + uniqueVariableName + " = " + operand.getText() + ";", parent); final PsiExpression initializer = ((PsiLocalVariable)declarationStatement.getDeclaredElements()[0]).getInitializer(); LOG.assertTrue(initializer != null, operand.getText()); opType = initializer.getType(); diff --git a/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java b/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java index c2b09bf50aa7..381eabc635d1 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java +++ b/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java @@ -36,8 +36,6 @@ public class TypesDistinctProver { } protected static boolean provablyDistinct(PsiType type1, PsiType type2, int level) { - if (type1 instanceof PsiClassType && ((PsiClassType)type1).resolve() instanceof PsiTypeParameter && level < 2) return false; - if (type2 instanceof PsiClassType && ((PsiClassType)type2).resolve() instanceof PsiTypeParameter && level < 2) return false; if (type1 instanceof PsiWildcardType) { if (type2 instanceof PsiWildcardType) { return provablyDistinct((PsiWildcardType)type1, (PsiWildcardType)type2, true); @@ -119,11 +117,33 @@ public class TypesDistinctProver { final PsiClass boundClass1 = classResolveResult1.getElement(); final PsiClass boundClass2 = classResolveResult2.getElement(); + + if (boundClass1 instanceof PsiTypeParameter && level < 2) { + if (!distinguishFromTypeParam((PsiTypeParameter)boundClass1, boundClass2, type1)) return false; + } + + if (boundClass2 instanceof PsiTypeParameter && level < 2) { + if (!distinguishFromTypeParam((PsiTypeParameter)boundClass2, boundClass1, type2)) return false; + } return type2 != null && type1 != null && !type1.equals(type2) && (!InheritanceUtil.isInheritorOrSelf(boundClass1, boundClass2, true) || !InheritanceUtil.isInheritorOrSelf(boundClass2, boundClass1, true)); } + private static boolean distinguishFromTypeParam(PsiTypeParameter typeParam, PsiClass boundClass, PsiType type1) { + final PsiClassType[] paramBounds = typeParam.getExtendsListTypes(); + if (paramBounds.length == 0 && type1 instanceof PsiClassType) return false; + for (PsiClassType classType : paramBounds) { + final PsiClass paramBound = classType.resolve(); + if (paramBound != null && + (InheritanceUtil.isInheritorOrSelf(paramBound, boundClass, true) || + InheritanceUtil.isInheritorOrSelf(boundClass, paramBound, true))) { + return false; + } + } + return true; + } + public static boolean provablyDistinct(PsiWildcardType type1, PsiWildcardType type2, boolean rejectInconsistentRaw) { if (type1.isSuper() && type2.isSuper()) return false; if (type1.isExtends() && type2.isExtends()) { diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java index 2b3359cf0498..11de0435a41d 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java @@ -376,7 +376,7 @@ public class ExceptionUtil { } @NotNull - public static List<PsiClassType> getUnhandledExceptions(PsiElement element) { + public static List<PsiClassType> getUnhandledExceptions(@NotNull PsiElement element) { if (element instanceof PsiCallExpression) { PsiCallExpression expression = (PsiCallExpression)element; return getUnhandledExceptions(expression, null); diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/JavaPsiEquivalenceUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/JavaPsiEquivalenceUtil.java index 730820392b67..fca20e67ecaa 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/JavaPsiEquivalenceUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/JavaPsiEquivalenceUtil.java @@ -17,6 +17,7 @@ package com.intellij.codeInsight; import com.intellij.psi.*; import com.intellij.psi.impl.source.PsiDiamondTypeElementImpl; +import com.intellij.psi.util.PsiTreeUtil; import java.util.Comparator; @@ -25,8 +26,15 @@ public class JavaPsiEquivalenceUtil { return PsiEquivalenceUtil.areElementsEquivalent(expr1, expr2, new Comparator<PsiElement>() { @Override public int compare(PsiElement o1, PsiElement o2) { - if (o1 instanceof PsiParameter && o2 instanceof PsiParameter && ((PsiParameter)o1).getDeclarationScope() instanceof PsiMethod) { - return ((PsiParameter)o1).getName().compareTo(((PsiParameter)o2).getName()); + if (o1 instanceof PsiParameter && o2 instanceof PsiParameter) { + final PsiElement scope1 = ((PsiParameter)o1).getDeclarationScope(); + final PsiElement scope2 = ((PsiParameter)o2).getDeclarationScope(); + if (scope1 instanceof PsiMethod && scope2 instanceof PsiMethod || + scope1 instanceof PsiLambdaExpression && scope2 instanceof PsiLambdaExpression) { + if (!scope1.getTextRange().intersects(scope2.getTextRange())) { + return ((PsiParameter)o1).getName().compareTo(((PsiParameter)o2).getName()); + } + } } return 1; } diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java index fe8804c617ef..712bbad96583 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java @@ -150,7 +150,7 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem } public static boolean hasErrorElementsNearby(final PsiFile file, int startOffset, int endOffset) { - endOffset = CharArrayUtil.shiftForward(file.getText(), endOffset, " \t\n"); + endOffset = CharArrayUtil.shiftForward(file.getViewProvider().getContents(), endOffset, " \t\n"); for (PsiElement element : CollectHighlightsUtil.getElementsInRange(file, startOffset, endOffset)) { if (element instanceof PsiErrorElement) { return true; diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java index 4a99129c3d88..5a1e1376ba93 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java @@ -30,6 +30,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.impl.JavaConstantExpressionEvaluator; +import com.intellij.psi.impl.source.javadoc.PsiInlineDocTagImpl; import com.intellij.psi.impl.source.tree.JavaDocElementType; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.javadoc.PsiDocTag; @@ -1039,7 +1040,7 @@ public class JavaDocInfoGenerator { generateLinkValue(tag, buffer, false); } else if (tagName.equals(LITERAL_TAG)) { - generateLiteralValue(tag, buffer); + generateLiteralValue(buffer, ((PsiInlineDocTagImpl)tag).getDataElementsIgnoreWhitespaces()); } else if (tagName.equals(CODE_TAG)) { generateCodeValue(tag, buffer); @@ -1073,14 +1074,12 @@ public class JavaDocInfoGenerator { @SuppressWarnings({"HardCodedStringLiteral"}) private static void generateCodeValue(PsiInlineDocTag tag, StringBuilder buffer) { buffer.append("<code>"); - generateLiteralValue(tag, buffer); + generateLiteralValue(buffer, tag.getDataElements()); buffer.append("</code>"); } - private static void generateLiteralValue(PsiInlineDocTag tag, StringBuilder buffer) { - PsiElement[] elements = tag.getDataElements(); - - for (PsiElement element : elements) { + private static void generateLiteralValue(StringBuilder buffer, final PsiElement[] dataElements) { + for (PsiElement element : dataElements) { appendPlainText(element.getText(), buffer); } } @@ -1489,6 +1488,7 @@ public class JavaDocInfoGenerator { if (!isAbstract) continue; } PsiClass superClass = superMethod.getContainingClass(); + if (superClass == null) continue; if (!headerGenerated) { buffer.append("<DD><DL>"); buffer.append("<DT><b>"); diff --git a/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java b/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java index ca2539195ee2..129be2e8d1aa 100644 --- a/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java @@ -28,6 +28,7 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.Function; +import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -136,7 +137,7 @@ public class PsiDiamondTypeImpl extends PsiDiamondType { final PsiMethod constructor = findConstructor(psiClass, newExpression); PsiTypeParameter[] params = getAllTypeParams(constructor, psiClass); - final PsiMethod staticFactory = generateStaticFactory(constructor, psiClass, params); + final PsiMethod staticFactory = generateStaticFactory(constructor, psiClass, params, newExpression.getClassReference()); if (staticFactory == null) { return null; } @@ -210,7 +211,10 @@ public class PsiDiamondTypeImpl extends PsiDiamondType { } @Nullable - private static PsiMethod generateStaticFactory(@Nullable PsiMethod constructor, PsiClass containingClass, PsiTypeParameter[] params) { + private static PsiMethod generateStaticFactory(@Nullable PsiMethod constructor, + PsiClass containingClass, + PsiTypeParameter[] params, + PsiJavaCodeReferenceElement reference) { final StringBuilder buf = new StringBuilder(); buf.append("public static "); buf.append("<"); @@ -223,7 +227,23 @@ public class PsiDiamondTypeImpl extends PsiDiamondType { }, ", ")); buf.append(">"); - final String qualifiedName = containingClass.getQualifiedName(); + final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(containingClass.getProject()); + + String qualifiedName = containingClass.getQualifiedName(); + + PsiElement qualifier = reference != null ? reference.getQualifier() : null; + if (qualifier instanceof PsiJavaCodeReferenceElement) { + final JavaResolveResult resolveResult = ((PsiJavaCodeReferenceElement)qualifier).advancedResolve(false); + final PsiElement element = resolveResult.getElement(); + if (element instanceof PsiClass) { + final String outerClassSubstitutedQName = + elementFactory.createType((PsiClass)element, resolveResult.getSubstitutor()).getInternalCanonicalText(); + qualifiedName = outerClassSubstitutedQName + "." + containingClass.getName(); + } + } else if (reference != null && qualifier == null && containingClass.getContainingClass() != null) { + qualifiedName = null; + } + buf.append(qualifiedName != null ? qualifiedName : containingClass.getName()); final PsiTypeParameter[] parameters = containingClass.getTypeParameters(); buf.append("<"); @@ -253,7 +273,12 @@ public class PsiDiamondTypeImpl extends PsiDiamondType { } buf.append("{}"); - return JavaPsiFacade.getElementFactory(containingClass.getProject()).createMethodFromText(buf.toString(), constructor != null ? constructor : containingClass); + try { + return elementFactory.createMethodFromText(buf.toString(), constructor != null ? constructor : containingClass); + } + catch (IncorrectOperationException e) { + return null; + } } private static PsiTypeParameter[] getAllTypeParams(PsiTypeParameterListOwner listOwner, PsiClass containingClass) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java index cf569860b069..b35a97e201ae 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java @@ -214,7 +214,8 @@ public class ClsFileImpl extends ClsRepositoryPsiElement<PsiClassHolderFileStub> @Override @NotNull public LanguageLevel getLanguageLevel() { - return LanguageLevel.HIGHEST; // library classes should inherit language level from modules where they are referenced + List stubs = getStub().getChildrenStubs(); + return !stubs.isEmpty() ? ((PsiClassStub<?>)stubs.get(0)).getLanguageLevel() : LanguageLevel.HIGHEST; } @Override @@ -289,7 +290,7 @@ public class ClsFileImpl extends ClsRepositoryPsiElement<PsiClassHolderFileStub> String fileName = (classes.length > 0 ? classes[0].getName() : file.getNameWithoutExtension()) + "." + ext; PsiFileFactory factory = PsiFileFactory.getInstance(getManager().getProject()); PsiFile mirror = factory.createFileFromText(fileName, JavaLanguage.INSTANCE, mirrorText, false, false); - mirror.putUserData(PsiUtil.FILE_LANGUAGE_LEVEL_KEY, getSourceLanguageLevel()); + mirror.putUserData(PsiUtil.FILE_LANGUAGE_LEVEL_KEY, getLanguageLevel()); mirrorTreeElement = SourceTreeToPsiMap.psiToTreeNotNull(mirror); // IMPORTANT: do not take lock too early - FileDocumentManager.saveToString() can run write action @@ -311,12 +312,6 @@ public class ClsFileImpl extends ClsRepositoryPsiElement<PsiClassHolderFileStub> return mirrorTreeElement.getPsi(); } - @NotNull - public LanguageLevel getSourceLanguageLevel() { - final List stubs = getStub().getChildrenStubs(); - return !stubs.isEmpty() ? ((PsiClassStub<?>)stubs.get(0)).getLanguageLevel() : LanguageLevel.HIGHEST; - } - @Override public PsiFile getDecompiledPsiFile() { for (ClsFileDecompiledPsiFileProvider provider : Extensions.getExtensions(ClsFileDecompiledPsiFileProvider.EP_NAME)) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiInlineDocTagImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiInlineDocTagImpl.java index 1adf3a5a700a..668453c71a70 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiInlineDocTagImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiInlineDocTagImpl.java @@ -35,10 +35,11 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlineDocTag, Constants { - private static final TokenSet TAG_VALUE_BIT_SET = TokenSet.create( - DOC_TAG_VALUE_ELEMENT, DOC_METHOD_OR_FIELD_REF); - private static final TokenSet VALUE_BIT_SET = TokenSet.orSet(TAG_VALUE_BIT_SET, TokenSet.create( + private static final TokenSet TAG_VALUE_BIT_SET = TokenSet.create(DOC_TAG_VALUE_ELEMENT, DOC_METHOD_OR_FIELD_REF); + private static final TokenSet VALUE_NO_WHITESPACE_BIT_SET = TokenSet.orSet(TAG_VALUE_BIT_SET, TokenSet.create( JAVA_CODE_REFERENCE, DOC_TAG_VALUE_TOKEN, DOC_COMMENT_DATA, DOC_INLINE_TAG, DOC_REFERENCE_HOLDER, DOC_COMMENT_BAD_CHARACTER)); + private static final TokenSet VALUE_BIT_SET = TokenSet.orSet(TAG_VALUE_BIT_SET, TokenSet.create( + JAVA_CODE_REFERENCE, DOC_TAG_VALUE_TOKEN, WHITE_SPACE, DOC_COMMENT_DATA, DOC_INLINE_TAG, DOC_REFERENCE_HOLDER, DOC_COMMENT_BAD_CHARACTER)); public PsiInlineDocTagImpl() { super(DOC_INLINE_TAG); @@ -63,6 +64,10 @@ public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlin return getChildrenAsPsiElements(VALUE_BIT_SET, PsiElement.ARRAY_FACTORY); } + public PsiElement[] getDataElementsIgnoreWhitespaces() { + return getChildrenAsPsiElements(VALUE_NO_WHITESPACE_BIT_SET, PsiElement.ARRAY_FACTORY); + } + @Override public PsiDocTagValue getValueElement() { return (PsiDocTagValue)findPsiChildByType(TAG_VALUE_BIT_SET); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java index 4110c82ca56e..b404ab4797f2 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java @@ -87,11 +87,16 @@ public class InferenceSession { initBounds(typeParams); } - public void initExpressionConstraints(PsiParameter[] parameters, PsiExpression[] args, PsiElement parent) { - final Pair<PsiMethod, PsiCallExpression> pair = getPair(parent); + public void initExpressionConstraints(PsiParameter[] parameters, PsiExpression[] args, PsiElement parent, PsiMethod method) { + if (method == null) { + final Pair<PsiMethod, PsiCallExpression> pair = getPair(parent); + if (pair != null) { + method = pair.first; + } + } if (parameters.length > 0) { for (int i = 0; i < args.length; i++) { - if (args[i] != null && (pair == null || isPertinentToApplicability(args[i], pair.first))) { + if (args[i] != null && isPertinentToApplicability(args[i], method)) { PsiType parameterType = getParameterType(parameters, args, i, mySiteSubstitutor); myConstraints.add(new ExpressionCompatibilityConstraint(args[i], parameterType)); } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiGraphInferenceHelper.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiGraphInferenceHelper.java index 6915b5f1c1c6..8b36b35e5c2c 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiGraphInferenceHelper.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiGraphInferenceHelper.java @@ -39,7 +39,7 @@ public class PsiGraphInferenceHelper implements PsiInferenceHelper { @Nullable PsiElement parent, @NotNull ParameterTypeInferencePolicy policy) { final InferenceSession inferenceSession = new InferenceSession(new PsiTypeParameter[]{typeParameter}, partialSubstitutor, myManager); - inferenceSession.initExpressionConstraints(parameters, arguments, parent); + inferenceSession.initExpressionConstraints(parameters, arguments, parent, null); return inferenceSession.infer(parameters, arguments, parent, policy).substitute(typeParameter); } @@ -54,7 +54,7 @@ public class PsiGraphInferenceHelper implements PsiInferenceHelper { @NotNull LanguageLevel languageLevel) { if (typeParameters.length == 0) return partialSubstitutor; final InferenceSession inferenceSession = new InferenceSession(typeParameters, partialSubstitutor, myManager); - inferenceSession.initExpressionConstraints(parameters, arguments, parent); + inferenceSession.initExpressionConstraints(parameters, arguments, parent, null); return inferenceSession.infer(parameters, arguments, parent, policy); } @@ -86,6 +86,14 @@ public class PsiGraphInferenceHelper implements PsiInferenceHelper { boolean isContraVariantPosition, LanguageLevel languageLevel) { if (arg == PsiType.VOID || param == PsiType.VOID) return PsiType.NULL; + if (param instanceof PsiArrayType && arg instanceof PsiArrayType) { + return getSubstitutionForTypeParameter(typeParam, ((PsiArrayType)param).getComponentType(), ((PsiArrayType)arg).getComponentType(), isContraVariantPosition, languageLevel); + } + + if (!(param instanceof PsiClassType)) return PsiType.NULL; + if (arg == null) { + return PsiType.NULL; + } final PsiType[] leftTypes; final PsiType[] rightTypes; if (isContraVariantPosition) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java index 68884aaf7915..4fe5dfb9722d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java @@ -97,7 +97,9 @@ public class CheckedExceptionCompatibilityConstraint extends InputOutputConstrai final List<PsiType> thrownTypes = new ArrayList<PsiType>(); if (myExpression instanceof PsiLambdaExpression) { PsiElement body = ((PsiLambdaExpression)myExpression).getBody(); - thrownTypes.addAll(ExceptionUtil.getUnhandledExceptions(body)); + if (body != null) { + thrownTypes.addAll(ExceptionUtil.getUnhandledExceptions(body)); + } } else { if (((PsiMethodReferenceExpression)myExpression).isExact()) { final PsiElement resolve = ((PsiMethodReferenceExpression)myExpression).resolve(); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java index 7fefdf5d5946..b433c13853f7 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java @@ -111,7 +111,7 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm InferenceSession callSession = new InferenceSession(typeParams, ((MethodCandidateInfo)resolveResult).getSiteSubstitutor(), myExpression.getManager()); final PsiExpression[] args = argumentList.getExpressions(); final PsiParameter[] parameters = method.getParameterList().getParameters(); - callSession.initExpressionConstraints(parameters, args, myExpression); + callSession.initExpressionConstraints(parameters, args, myExpression, method); substitutor = callSession.infer(parameters, args, myExpression, LiftParameterTypeInferencePolicy.INSTANCE); } } else { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java index 3c836558cc9d..555b53b908eb 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java @@ -115,8 +115,11 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm constraints.add(new TypeCompatibilityConstraint(GenericsUtil.eliminateWildcards(returnType), psiSubstitutor.substitute(applicableMethodReturnType))); } else if (applicableMember instanceof PsiClass || applicableMember instanceof PsiMethod && ((PsiMethod)applicableMember).isConstructor()) { final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(applicableMember.getProject()); - final PsiClassType classType = elementFactory.createType(qualifierResolveResult.getContainingClass(), psiSubstitutor); - constraints.add(new TypeCompatibilityConstraint(GenericsUtil.eliminateWildcards(returnType), classType)); + final PsiClass containingClass = qualifierResolveResult.getContainingClass(); + if (containingClass != null) { + final PsiClassType classType = elementFactory.createType(containingClass, psiSubstitutor); + constraints.add(new TypeCompatibilityConstraint(GenericsUtil.eliminateWildcards(returnType), classType)); + } } } return true; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java index c6fb44b0d993..a52efdf6c82b 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java @@ -606,8 +606,17 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase } @Override - protected boolean checkSameConflicts(CandidateInfo method, CandidateInfo conflict) { - return method == conflict; + protected boolean nonComparable(CandidateInfo method, CandidateInfo conflict) { + if (method == conflict) return true; + PsiElement psiElement = method.getElement(); + PsiElement conflictElement = conflict.getElement(); + if (psiElement instanceof PsiMethod && conflictElement instanceof PsiMethod) { + if (((PsiMethod)psiElement).getParameterList().getParametersCount() != + ((PsiMethod)conflictElement).getParameterList().getParametersCount()) { + return true; + } + } + return false; } } } diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java index 94b4d4512fa7..22cc0512cd90 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java @@ -145,7 +145,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ for (int j = 0; j < i; j++) { ProgressManager.checkCanceled(); final CandidateInfo conflict = newConflictsArray[j]; - if (checkSameConflicts(method, conflict)) continue; + if (nonComparable(method, conflict)) continue; switch (isMoreSpecific(method, conflict, applicabilityLevel, languageLevel)) { case FIRST: conflicts.remove(conflict); @@ -161,7 +161,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ } } - protected boolean checkSameConflicts(CandidateInfo method, CandidateInfo conflict) { + protected boolean nonComparable(CandidateInfo method, CandidateInfo conflict) { assert method != conflict; return false; } @@ -509,8 +509,22 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ final PsiType[] types2AtSite = typesAtSite(types2, siteSubstitutor2); final PsiType[] types1AtSite = typesAtSite(types1, siteSubstitutor1); - final boolean applicable12 = isApplicableTo(types2AtSite, method1, typeParameters1, languageLevel, varargsPosition, types1, siteSubstitutor1); - final boolean applicable21 = isApplicableTo(types1AtSite, method2, typeParameters2, languageLevel, varargsPosition, types2, siteSubstitutor2); + final PsiSubstitutor methodSubstitutor1 = calculateMethodSubstitutor(typeParameters1, method1, siteSubstitutor1, types1, types2AtSite, languageLevel); + boolean applicable12 = isApplicableTo(types2AtSite, method1, languageLevel, varargsPosition, methodSubstitutor1); + + final PsiSubstitutor methodSubstitutor2 = calculateMethodSubstitutor(typeParameters2, method2, siteSubstitutor2, types2, types1AtSite, languageLevel); + boolean applicable21 = isApplicableTo(types1AtSite, method2, languageLevel, varargsPosition, methodSubstitutor2); + + final boolean typeArgsApplicable12 = GenericsUtil.isTypeArgumentsApplicable(typeParameters1, methodSubstitutor1, myArgumentsList, !applicable21); + final boolean typeArgsApplicable21 = GenericsUtil.isTypeArgumentsApplicable(typeParameters2, methodSubstitutor2, myArgumentsList, !applicable12); + + if (!typeArgsApplicable12) { + applicable12 = false; + } + + if (!typeArgsApplicable21) { + applicable21 = false; + } if (applicable12 || applicable21) { @@ -538,8 +552,10 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ } if (toCompareFunctional) { - final boolean applicable12ignoreFunctionalType = isApplicableTo(types2AtSite, method1, typeParameters1, languageLevel, varargsPosition, types1, siteSubstitutor1); - final boolean applicable21ignoreFunctionalType = isApplicableTo(types1AtSite, method2, typeParameters2, languageLevel, varargsPosition, types2, siteSubstitutor2); + final boolean applicable12ignoreFunctionalType = isApplicableTo(types2AtSite, method1, languageLevel, varargsPosition, + calculateMethodSubstitutor(typeParameters1, method1, siteSubstitutor1, types1, types2AtSite, languageLevel)); + final boolean applicable21ignoreFunctionalType = isApplicableTo(types1AtSite, method2, languageLevel, varargsPosition, + calculateMethodSubstitutor(typeParameters2, method2, siteSubstitutor2, types2, types1AtSite, languageLevel)); if (applicable12ignoreFunctionalType || applicable21ignoreFunctionalType) { Specifics specifics = null; @@ -616,18 +632,13 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ return Specifics.NEITHER; } - private boolean isApplicableTo(PsiType[] types2AtSite, - PsiMethod method1, - PsiTypeParameter[] typeParameters1, - LanguageLevel languageLevel, - boolean varargsPosition, PsiType[] types1, PsiSubstitutor siteSubstitutor1) { - final PsiSubstitutor methodSubstitutor1 = calculateMethodSubstitutor(typeParameters1, method1, siteSubstitutor1, types1, types2AtSite, languageLevel); + private static boolean isApplicableTo(PsiType[] types2AtSite, + PsiMethod method1, + LanguageLevel languageLevel, + boolean varargsPosition, + final PsiSubstitutor methodSubstitutor1) { final int applicabilityLevel = PsiUtil.getApplicabilityLevel(method1, methodSubstitutor1, types2AtSite, languageLevel, false, varargsPosition); - final boolean applicable = applicabilityLevel > MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE; - if (applicable && !GenericsUtil.isTypeArgumentsApplicable(typeParameters1, methodSubstitutor1, myArgumentsList, false)) { - return false; - } - return applicable; + return applicabilityLevel > MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE; } private static PsiType[] typesAtSite(PsiType[] types1, PsiSubstitutor siteSubstitutor1) { @@ -650,7 +661,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ ProgressManager.checkCanceled(); LOG.assertTrue(typeParameter != null); if (!substitutor.getSubstitutionMap().containsKey(typeParameter)) { - substitutor = substitutor.put(typeParameter, siteSubstitutor.substitute(typeParameter)); + substitutor = substitutor.put(typeParameter, TypeConversionUtil.erasure(siteSubstitutor.substitute(typeParameter), substitutor)); } } return substitutor; diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java b/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java index 8556ee13e513..30f908426cd6 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java @@ -25,6 +25,7 @@ package com.intellij.psi.scope.util; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicatorProvider; +import com.intellij.openapi.util.Comparing; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.JavaResolveUtil; @@ -318,7 +319,13 @@ public class PsiScopesUtil { if (initializer instanceof PsiNewExpression) { final PsiAnonymousClass anonymousClass = ((PsiNewExpression)initializer).getAnonymousClass(); if (anonymousClass != null && type.equals(anonymousClass.getBaseClassType())) { - type = initializer.getType(); + final PsiMethod[] refMethods = anonymousClass.findMethodsByName(methodCall.getMethodExpression().getReferenceName(), false); + if (refMethods.length > 0) { + final PsiClass baseClass = PsiUtil.resolveClassInType(type); + if (baseClass != null && !hasCovariantOverriding(baseClass, refMethods)) { + type = initializer.getType(); + } + } } } } @@ -381,6 +388,18 @@ public class PsiScopesUtil { } } + private static boolean hasCovariantOverriding(PsiClass baseClass, PsiMethod[] refMethods) { + for (PsiMethod method : refMethods) { + final PsiType methodReturnType = method.getReturnType(); + for (PsiMethod superMethod : method.findSuperMethods(baseClass)) { + if (!Comparing.equal(methodReturnType, superMethod.getReturnType())) { + return true; + } + } + } + return false; + } + private static boolean processQualifierType(@NotNull final PsiType type, final MethodsProcessor processor, PsiManager manager, diff --git a/java/java-tests/java-tests.iml b/java/java-tests/java-tests.iml index cc0afca03321..01e606b3b118 100644 --- a/java/java-tests/java-tests.iml +++ b/java/java-tests/java-tests.iml @@ -30,6 +30,7 @@ <orderEntry type="module" module-name="java-indexing-api" scope="TEST" /> <orderEntry type="module" module-name="external-system-impl" scope="RUNTIME" /> <orderEntry type="module" module-name="junit_rt" scope="TEST" /> + <orderEntry type="module" module-name="xml-psi-impl" scope="TEST" /> </component> </module> diff --git a/java/java-tests/testData/codeInsight/completion/smartType/FilteredMethodReference-out.java b/java/java-tests/testData/codeInsight/completion/smartType/FilteredMethodReference-out.java new file mode 100644 index 000000000000..2086ad1bbf39 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/FilteredMethodReference-out.java @@ -0,0 +1,13 @@ +class Test { + interface I { + int foo(); + } + + static int aa() { + return 0; + } + + { + I i = Test::aa + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/smartType/FilteredMethodReference.java b/java/java-tests/testData/codeInsight/completion/smartType/FilteredMethodReference.java new file mode 100644 index 000000000000..f49bb50c7bbb --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/FilteredMethodReference.java @@ -0,0 +1,13 @@ +class Test { + interface I { + int foo(); + } + + static int aa() { + return 0; + } + + { + I i = Test::<caret> + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/smartType/InferFromRawType.java b/java/java-tests/testData/codeInsight/completion/smartType/InferFromRawType.java new file mode 100644 index 000000000000..8a2ea295de31 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/InferFromRawType.java @@ -0,0 +1,5 @@ +class A<T extends String> { + { + A a = new A<<caret>>(); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/smartType/NotAvailableInLambdaPositionAfterQualifier.java b/java/java-tests/testData/codeInsight/completion/smartType/NotAvailableInLambdaPositionAfterQualifier.java new file mode 100644 index 000000000000..f7523c61078d --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/NotAvailableInLambdaPositionAfterQualifier.java @@ -0,0 +1,9 @@ +class Test { + interface I { + void foo(); + } + + { + I i = Unknown::<caret> + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/wrongPlace.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/wrongPlace.java index ab1d2f0273e0..581948e6ed2b 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/wrongPlace.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/wrongPlace.java @@ -27,4 +27,10 @@ interface I { @interface Caller { Anno anno() default @Anno; -}
\ No newline at end of file +} + +@interface AnnoArray { + @interface Part { } + + Part[] arrayValue() default {@Part, @Part}; +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA104160.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA104160.java index 92e5b57c39e4..32d2c84e40da 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA104160.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA104160.java @@ -10,4 +10,9 @@ class Test<T> { class B extends ArrayList<T> { void foo(T r){} } + + static class C extends Test<<error descr="'Test.this' cannot be referenced from a static context">T</error>> {} + static class D extends Test { + <error descr="'Test.this' cannot be referenced from a static context">T</error> t; + } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA117827.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA117827.java new file mode 100644 index 000000000000..afa7d2a52de3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA117827.java @@ -0,0 +1,16 @@ + +import java.util.Collection; +import java.util.List; + +public class Testsss { + + public <TA, CA extends Iterable<TA>> void that(Iterable<TA> target) {} + + public <T, C extends Collection<T>> void that(Collection<T> target) {} + + void foo(ImmutableList<String> l) { + that( l); + } + + interface ImmutableList<T> extends List<T> {} +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA118037.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA118037.java new file mode 100644 index 000000000000..47ff27a0bfca --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA118037.java @@ -0,0 +1,14 @@ +final class Test +{ + class Foo + { + <T extends String> void foo(Class<T> clazz) + { + if (<error descr="Operator '==' cannot be applied to 'java.lang.Class<java.lang.Void>', 'java.lang.Class<T>'">Void.class == clazz</error>) + { + System.out.println("Yeah!"); + } + } + } +} + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/diamond/OuterClass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/diamond/OuterClass.java new file mode 100644 index 000000000000..d69d551da77d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/diamond/OuterClass.java @@ -0,0 +1,23 @@ +import java.util.*; + +class HT<O> { + private Iterator<O> getIterator(int type, int count) { + return new Enumerator<>(type, true); + } + + private class Enumerator<T> implements Iterator<T> { + + public Enumerator(int type, boolean b) { + } + + @Override + public boolean hasNext() { + return false; + } + + @Override + public T next() { + return null; + } + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ResolveConflicts.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ResolveConflicts.java index 681e207b23f7..919a623da826 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ResolveConflicts.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ResolveConflicts.java @@ -6,7 +6,7 @@ interface Func<TIn, TOut>{ class Main { public static void main(final String[] args) { - Func<Integer, String> func = Integer::toString; + <error descr="Incompatible types. Found: '<method reference>', required: 'Func<java.lang.Integer,java.lang.String>'">Func<Integer, String> func = Integer::toString;</error> System.out.println(func.run(6)); } }
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/ArgumentOfAnonymousClass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/ArgumentOfAnonymousClass.java new file mode 100644 index 000000000000..dfd4563e5a82 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/ArgumentOfAnonymousClass.java @@ -0,0 +1,19 @@ +interface I<T> { + void accept(T t); +} + +class LamdbaTest<T> { + + public void f() { + new A<T>(t -> g(t)) {}; + } + + private void g(T t) { + } + + class A<T2> { + public A(I<T> editor) { + } + } + +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/Ellipsis.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/Ellipsis.java new file mode 100644 index 000000000000..63427857adc9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/Ellipsis.java @@ -0,0 +1,9 @@ +interface Var { + void var(int... ps); +} + +class Abc { + void foo() { + Var var = (int[] ps) -> {}; + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/OuterMethodPropagation.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/OuterMethodPropagation.java new file mode 100644 index 000000000000..b19ca63591f7 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/OuterMethodPropagation.java @@ -0,0 +1,17 @@ +public class Tmp +{ + interface BiFunction<T, U, R> { + R apply(T t, U u); + } + + interface Sequence<T> + { + <R> Sequence<R> scan(R init, BiFunction<R, T, R> func); + } + + static <T> void foo(Sequence<T> sequence){} + + void test(Sequence<String> strings) { + foo(strings.scan(1, (i, s) -> 1)); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArgumentsConditional/afterEliminateWildcards.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArgumentsConditional/afterEliminateWildcards.java new file mode 100644 index 000000000000..a228257636cc --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArgumentsConditional/afterEliminateWildcards.java @@ -0,0 +1,12 @@ +// "Add explicit type arguments" "true" +import java.util.*; + +class Test { + static class A {} + static class B extends A {} + + + public Collection<? extends A> run(boolean flag) { + return flag ? Collections.singletonList(new B()) : Collections.<A>emptyList(); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArgumentsConditional/beforeEliminateWildcards.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArgumentsConditional/beforeEliminateWildcards.java new file mode 100644 index 000000000000..8d4383c05752 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArgumentsConditional/beforeEliminateWildcards.java @@ -0,0 +1,12 @@ +// "Add explicit type arguments" "true" +import java.util.*; + +class Test { + static class A {} + static class B extends A {} + + + public Collection<? extends A> run(boolean flag) { + return flag ? Collections.singletonList(new B()) : Collections.<caret>emptyList(); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/beforeSideEffects.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/beforeSideEffects.java new file mode 100644 index 000000000000..754a9eaebf83 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/beforeSideEffects.java @@ -0,0 +1,13 @@ +// "Replace with method reference" "false" +class Test { + public interface I { + String m(); + } + + public static void main(String[] args) { + I<String> supplier = () -> new Ob<caret>ject().toString(); + + System.out.println(supplier.get()); + System.out.println(supplier.get()); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterAmbiguousMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterAmbiguousMethods.java new file mode 100644 index 000000000000..475f46eabdff --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterAmbiguousMethods.java @@ -0,0 +1,10 @@ +// "Replace lambda with method reference" "true" +class Example { + interface I { + String foo(Integer i); + } + + { + I i = Object::toString; + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeAmbiguousMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeAmbiguousMethods.java new file mode 100644 index 000000000000..b731848f445c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeAmbiguousMethods.java @@ -0,0 +1,10 @@ +// "Replace lambda with method reference" "true" +class Example { + interface I { + String foo(Integer i); + } + + { + I i = (i1) -> i1.<caret>toString(); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadocIG/code.html b/java/java-tests/testData/codeInsight/javadocIG/code.html new file mode 100644 index 000000000000..e75e09176a2f --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadocIG/code.html @@ -0,0 +1,10 @@ +<html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><small><b><a href="psi_element://Foo"><code>Foo</code></a></b></small><PRE>int <b>foo</b></PRE> + <pre> + <code> + class Clazzz { + def f[U](u: U) {} + + val a = 1 + } + </code> + </pre></body></html>
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadocIG/code.java b/java/java-tests/testData/codeInsight/javadocIG/code.java new file mode 100644 index 000000000000..f5cf2a77f600 --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadocIG/code.java @@ -0,0 +1,14 @@ +class Foo { + /** + * <pre> + * {@code + * class Clazzz { + * def f[U](u: U) {} + * + * val a = 1 + * } + * } + * </pre> + */ + int foo; +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/parameterInfo/SelectionWithGenerics.java b/java/java-tests/testData/codeInsight/parameterInfo/SelectionWithGenerics.java new file mode 100644 index 000000000000..cfafbdb8134c --- /dev/null +++ b/java/java-tests/testData/codeInsight/parameterInfo/SelectionWithGenerics.java @@ -0,0 +1,12 @@ +class Test { + { + refresh(<caret>false, false, null, ""); + } + + public final void refresh(boolean async, boolean recursive, Runnable finishRunnable, String... files) { + } + + public final void refresh(boolean async, boolean recursive, Runnable finishRunnable, Integer files) { + } + +} diff --git a/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass.log b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass.log new file mode 100644 index 000000000000..228bc41f8f7e --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass.log @@ -0,0 +1,11 @@ +Compiling files: +src/package2/A.java +End of files +Cleaning output files: +out/production/AddClassHidingImportedClass/package2/B.class +out/production/AddClassHidingImportedClass/package3/C.class +End of files +Compiling files: +src/package2/B.java +src/package3/C.java +End of files diff --git a/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package1/A.java b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package1/A.java new file mode 100644 index 000000000000..a61ecd9b2705 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package1/A.java @@ -0,0 +1,7 @@ +package package1; + +public class A { + public static class D { + public final String s = new String("package1"); + } +} diff --git a/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package2/A.java.new b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package2/A.java.new new file mode 100644 index 000000000000..98b0feeffca2 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package2/A.java.new @@ -0,0 +1,7 @@ +package package2; + +public class A { + public static class D { + public final String s = new String("package2"); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package2/B.java b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package2/B.java new file mode 100644 index 000000000000..a32b694a09c8 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package2/B.java @@ -0,0 +1,6 @@ +package package2; +import package1.*; + +public class B extends A{ + +} diff --git a/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package3/C.java b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package3/C.java new file mode 100644 index 000000000000..04d86d390ea6 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package3/C.java @@ -0,0 +1,14 @@ +package package3; + +import package2.B; + +public class C { + + public B.D p; + + public String get() { + p = new B.D(); + return p.s; + } + +} diff --git a/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass2.log b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass2.log new file mode 100644 index 000000000000..8564c55fc97f --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass2.log @@ -0,0 +1,15 @@ +Cleaning output files: +out/production/AddClassHidingImportedClass2/package3/C.class +End of files +Compiling files: +src/package2/A.java +src/package3/C.java +End of files +Cleaning output files: +out/production/AddClassHidingImportedClass2/package2/B.class +out/production/AddClassHidingImportedClass2/package3/C.class +End of files +Compiling files: +src/package2/B.java +src/package3/C.java +End of files diff --git a/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass2/src/package1/A.java b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass2/src/package1/A.java new file mode 100644 index 000000000000..a61ecd9b2705 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass2/src/package1/A.java @@ -0,0 +1,7 @@ +package package1; + +public class A { + public static class D { + public final String s = new String("package1"); + } +} diff --git a/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass2/src/package2/A.java.new b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass2/src/package2/A.java.new new file mode 100644 index 000000000000..98b0feeffca2 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass2/src/package2/A.java.new @@ -0,0 +1,7 @@ +package package2; + +public class A { + public static class D { + public final String s = new String("package2"); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass2/src/package2/B.java b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass2/src/package2/B.java new file mode 100644 index 000000000000..a32b694a09c8 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass2/src/package2/B.java @@ -0,0 +1,6 @@ +package package2; +import package1.*; + +public class B extends A{ + +} diff --git a/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass2/src/package3/C.java b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass2/src/package3/C.java new file mode 100644 index 000000000000..6ba1003dcad0 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass2/src/package3/C.java @@ -0,0 +1,15 @@ +package package3; + +import package2.B; + +public class C { + + public B.D p; + + public String get() { + p = new B.D(); + return p.s; + } + + public void dummy() {} +} diff --git a/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass2/src/package3/C.java.new b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass2/src/package3/C.java.new new file mode 100644 index 000000000000..5074eb231081 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass2/src/package3/C.java.new @@ -0,0 +1,16 @@ +package package3; + +import package2.B; + +public class C { + + public B.D p; + + public String get() { + p = new B.D(); + return p.s; + } + + // commenting dummy method => causing class change => compilation on the first round + // public void dummy() {} +} diff --git a/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain.log b/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain.log index 37245f2de1f0..278d40b50f5b 100644 --- a/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain.log +++ b/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain.log @@ -12,3 +12,9 @@ Compiling files: src/Client.java src/ServerClient.java End of files +Cleaning output files: +out/production/ConstantChain/Server.class +End of files +Compiling files: +src/Server.java +End of files diff --git a/java/java-tests/testData/compileServer/incremental/fieldProperties/mutualConstants.log b/java/java-tests/testData/compileServer/incremental/fieldProperties/mutualConstants.log new file mode 100644 index 000000000000..e4b795d0740d --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/fieldProperties/mutualConstants.log @@ -0,0 +1,16 @@ +Cleaning output files: +out/production/MutualConstants/constants/B.class +End of files +Compiling files: +src/constants/B.java +End of files +Cleaning output files: +out/production/MutualConstants/constants/A.class +out/production/MutualConstants/constants/B.class +out/production/MutualConstants/constants/PrintConst.class +End of files +Compiling files: +src/constants/A.java +src/constants/B.java +src/constants/PrintConst.java +End of files diff --git a/java/java-tests/testData/compileServer/incremental/fieldProperties/mutualConstants/src/constants/A.java b/java/java-tests/testData/compileServer/incremental/fieldProperties/mutualConstants/src/constants/A.java new file mode 100644 index 000000000000..b81709360d38 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/fieldProperties/mutualConstants/src/constants/A.java @@ -0,0 +1,5 @@ +package constants; + +public class A { + public static final int CONST_A = B.CONST_B_1 + 1; +} diff --git a/java/java-tests/testData/compileServer/incremental/fieldProperties/mutualConstants/src/constants/B.java b/java/java-tests/testData/compileServer/incremental/fieldProperties/mutualConstants/src/constants/B.java new file mode 100644 index 000000000000..e3a2d4fefb59 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/fieldProperties/mutualConstants/src/constants/B.java @@ -0,0 +1,5 @@ +package constants; +public class B { + public static final int CONST_B_1 = 0; + public static final int CONST_B_2 = A.CONST_A + 1; +} diff --git a/java/java-tests/testData/compileServer/incremental/fieldProperties/mutualConstants/src/constants/B.java.new b/java/java-tests/testData/compileServer/incremental/fieldProperties/mutualConstants/src/constants/B.java.new new file mode 100644 index 000000000000..7ccf22ffad7c --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/fieldProperties/mutualConstants/src/constants/B.java.new @@ -0,0 +1,5 @@ +package constants; +public class B { + public static final int CONST_B_1 = 1; + public static final int CONST_B_2 = A.CONST_A + 1; +} diff --git a/java/java-tests/testData/compileServer/incremental/fieldProperties/mutualConstants/src/constants/PrintConst.java b/java/java-tests/testData/compileServer/incremental/fieldProperties/mutualConstants/src/constants/PrintConst.java new file mode 100644 index 000000000000..ccf17f812df3 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/fieldProperties/mutualConstants/src/constants/PrintConst.java @@ -0,0 +1,7 @@ +package constants; + +public class PrintConst { + public static void main(String[] args) { + System.out.println(B.CONST_B_2); + } +} diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/PrimitiveCastMayChangeValue.java b/java/java-tests/testData/inspection/dataFlow/fixture/PrimitiveCastMayChangeValue.java index 652f0dccc9d6..cfe0d0e1bcf4 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/PrimitiveCastMayChangeValue.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/PrimitiveCastMayChangeValue.java @@ -10,6 +10,10 @@ public class BrokenAlignment { } else { System.out.println("4"); } + + if (0 == (long)<error descr="Cannot resolve symbol 'i'">i</error>) { + System.out.println("0"); + } } }
\ No newline at end of file diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ReturnNullInLambdaExpression.java b/java/java-tests/testData/inspection/dataFlow/fixture/ReturnNullInLambdaExpression.java new file mode 100644 index 000000000000..92d0f422d0bf --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/ReturnNullInLambdaExpression.java @@ -0,0 +1,12 @@ +import org.jetbrains.annotations.NotNull; + +class Test { + interface I { + @NotNull + String get(); + } + + { + I i = () -> <warning descr="'null' is returned by the method declared as @NotNull">null</warning>; + } +} diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ReturnNullInLambdaStatement.java b/java/java-tests/testData/inspection/dataFlow/fixture/ReturnNullInLambdaStatement.java new file mode 100644 index 000000000000..0566fcec540a --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/ReturnNullInLambdaStatement.java @@ -0,0 +1,12 @@ +import org.jetbrains.annotations.NotNull; + +class Test { + interface I { + @NotNull + String get(); + } + + { + I i = () -> {return <warning descr="'null' is returned by the method declared as @NotNull">null</warning>;}; + } +} diff --git a/java/java-tests/testData/inspection/localCanBeFinal/For/src/For.java b/java/java-tests/testData/inspection/localCanBeFinal/For/src/For.java index 529844bc5326..4a10521bf860 100644 --- a/java/java-tests/testData/inspection/localCanBeFinal/For/src/For.java +++ b/java/java-tests/testData/inspection/localCanBeFinal/For/src/For.java @@ -1,7 +1,8 @@ class For { void f(List<String> list) { - for (Iterator<String> it = list.iterator(); it.hasNext();) { // 'it' can be final but not reported + for (Iterator<String> it = list.iterator(); it.hasNext();) { } for (int i = 0; i < 10; i++) {} + for (int i = 0, length = 10; i < length; i++) {} } }
\ No newline at end of file diff --git a/java/java-tests/testData/inspection/redundantCast/generics/SafeTempVarName/expected.xml b/java/java-tests/testData/inspection/redundantCast/generics/SafeTempVarName/expected.xml new file mode 100644 index 000000000000..4704d91e891d --- /dev/null +++ b/java/java-tests/testData/inspection/redundantCast/generics/SafeTempVarName/expected.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<problems/>
\ No newline at end of file diff --git a/java/java-tests/testData/inspection/redundantCast/generics/SafeTempVarName/src/Test.java b/java/java-tests/testData/inspection/redundantCast/generics/SafeTempVarName/src/Test.java new file mode 100644 index 000000000000..c7fa33b277f8 --- /dev/null +++ b/java/java-tests/testData/inspection/redundantCast/generics/SafeTempVarName/src/Test.java @@ -0,0 +1,9 @@ +import java.util.*; + +public class RedundantCast{ + <T> void foo2(List<Object[]> x) { + for (Object[] l : x) { + String[] s = (String[]) l; + } + } +} diff --git a/java/java-tests/testData/inspection/redundantTypeArgs/NestedCalls.java b/java/java-tests/testData/inspection/redundantTypeArgs/NestedCalls.java new file mode 100644 index 000000000000..9121bda1706a --- /dev/null +++ b/java/java-tests/testData/inspection/redundantTypeArgs/NestedCalls.java @@ -0,0 +1,18 @@ +import java.io.Serializable; + +final class Expected { + public static <P extends Serializable> Expected make(final P good) { + return null; + } +} + +interface Serializer { + <T> T deserialize(final Class<T> type); +} + +class FooBar { + <T extends Serializable> void invoke(final Class<T> rpc, final Serializer serializer) { + Expected.make(serializer.<warning descr="Explicit type arguments can be inferred"><T></warning>deserialize(rpc)); + } +} + diff --git a/java/java-tests/testData/psi/formatter/java/FormatterOnOffTags.java b/java/java-tests/testData/psi/formatter/java/FormatterOnOffTags.java index 93e69f10db5c..e0168308c0f5 100644 --- a/java/java-tests/testData/psi/formatter/java/FormatterOnOffTags.java +++ b/java/java-tests/testData/psi/formatter/java/FormatterOnOffTags.java @@ -17,8 +17,12 @@ public class CollectionTest { str3 = "Green", str4 = "Blue"; // @formatter:on + if (true) + System.out.println("True"); Iterator iterator; // @formatter:off + if (true) + System.out.println("True"); collection.add(str1); collection.add(str2); collection.add(str3); @@ -39,6 +43,9 @@ public class CollectionTest { * And yet another one. */ public void doSomething(String x, String y) { + if + (true) + System.out.println("True"); } // @formatter:on @@ -47,7 +54,10 @@ public class CollectionTest { * @param z * Parameter Z. */ - public void doSomethingElse(String z) {} + public void doSomethingElse(String z) { + if (true) + System.out.println("True"); + } // @formatter:off /** @@ -57,6 +67,10 @@ public class CollectionTest { * @param j * Parameter J. */ - public void evenMore(int i, int j) {} + public void evenMore(int i, int j) { + if + (true) + System.out.println("True"); + } // @formatter:on } diff --git a/java/java-tests/testData/psi/formatter/java/FormatterOnOffTags_after.java b/java/java-tests/testData/psi/formatter/java/FormatterOnOffTags_after.java index 01233b3ac32e..e0102b614d3c 100644 --- a/java/java-tests/testData/psi/formatter/java/FormatterOnOffTags_after.java +++ b/java/java-tests/testData/psi/formatter/java/FormatterOnOffTags_after.java @@ -17,8 +17,13 @@ public class CollectionTest { str3 = "Green", str4 = "Blue"; // @formatter:on + if (true) { + System.out.println("True"); + } Iterator iterator; // @formatter:off + if (true) + System.out.println("True"); collection.add(str1); collection.add(str2); collection.add(str3); @@ -39,6 +44,9 @@ public class CollectionTest { * And yet another one. */ public void doSomething(String x, String y) { + if + (true) + System.out.println("True"); } // @formatter:on @@ -48,6 +56,9 @@ public class CollectionTest { * @param z Parameter Z. */ public void doSomethingElse(String z) { + if (true) { + System.out.println("True"); + } } // @formatter:off @@ -58,6 +69,10 @@ public class CollectionTest { * @param j * Parameter J. */ - public void evenMore(int i, int j) {} + public void evenMore(int i, int j) { + if + (true) + System.out.println("True"); + } // @formatter:on } diff --git a/java/java-tests/testData/psi/resolve/method/generics/CovariantReturnTypeAnonymous.java b/java/java-tests/testData/psi/resolve/method/generics/CovariantReturnTypeAnonymous.java new file mode 100644 index 000000000000..b487a309af24 --- /dev/null +++ b/java/java-tests/testData/psi/resolve/method/generics/CovariantReturnTypeAnonymous.java @@ -0,0 +1,20 @@ +interface X { + A[] foo(); +} + +class A {} + +class B extends A {} + +class C { + final X x = new X() { + @Override + public B[] foo() { + return new B[0]; + } + }; + + B[] bar() { + return x.f<ref>oo(); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineParameter/FromClassInitializer.java b/java/java-tests/testData/refactoring/inlineParameter/FromClassInitializer.java new file mode 100644 index 000000000000..ecb1a4ab1e64 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineParameter/FromClassInitializer.java @@ -0,0 +1,10 @@ +class X { + { + String str = ""; + foo(str, str.substring(0)); + } + + void foo(String str, String st<caret>r1) { + + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineParameter/FromClassInitializer.java.after b/java/java-tests/testData/refactoring/inlineParameter/FromClassInitializer.java.after new file mode 100644 index 000000000000..167339be0630 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineParameter/FromClassInitializer.java.after @@ -0,0 +1,10 @@ +class X { + { + String str = ""; + foo(str); + } + + void foo(String str) { + + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceVariable/AnonymousClass3.after.java b/java/java-tests/testData/refactoring/introduceVariable/AnonymousClass3.after.java new file mode 100644 index 000000000000..e32601702102 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/AnonymousClass3.after.java @@ -0,0 +1,27 @@ +import java.io.PrintStream; +class Foo { + + public static void bazz(int i) { + Foo j = new Foo(new IBar() { + public void doSomething(PrintStream out) { + out.println("hello"); + } + }); + final Foo foo = i != 0 ? j : j; + foo.bla(); + } + + private final IBar bar; + + public Foo(IBar bar) { + this.bar = bar; + } + + public void bla() { + bar.doSomething(System.out); + } + + public interface IBar { + void doSomething(PrintStream out); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceVariable/AnonymousClass3.java b/java/java-tests/testData/refactoring/introduceVariable/AnonymousClass3.java new file mode 100644 index 000000000000..b2f3688b2cb2 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/AnonymousClass3.java @@ -0,0 +1,30 @@ +import java.io.PrintStream; +class Foo { + + public static void bazz(int i) { + final Foo foo = i != 0 ? <selection>new Foo(new IBar() { + public void doSomething(PrintStream out) { + out.println("hello"); + } + })</selection> : new Foo(new IBar() { + public void doSomething(PrintStream out) { + out.println("hello"); + } + }); + foo.bla(); + } + + private final IBar bar; + + public Foo(IBar bar) { + this.bar = bar; + } + + public void bla() { + bar.doSomething(System.out); + } + + public interface IBar { + void doSomething(PrintStream out); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceVariable/AnonymousClass4.after.java b/java/java-tests/testData/refactoring/introduceVariable/AnonymousClass4.after.java new file mode 100644 index 000000000000..4642ab3a27ee --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/AnonymousClass4.after.java @@ -0,0 +1,22 @@ + +import java.util.ArrayList; +import java.util.Collection; + +public class ExtractVariableSample { + + public static void main(String[] args) { + Collection<String> strings = new ArrayList<>(); + new Object() { + public void foo(String s) { + System.out.println( s.hashCode()); + } + }; + + for (String s : strings) { + int j = s.hashCode(); + System.out.println(j); + } + } + + +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceVariable/AnonymousClass4.java b/java/java-tests/testData/refactoring/introduceVariable/AnonymousClass4.java new file mode 100644 index 000000000000..1415fc9a9abc --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/AnonymousClass4.java @@ -0,0 +1,21 @@ + +import java.util.ArrayList; +import java.util.Collection; + +public class ExtractVariableSample { + + public static void main(String[] args) { + Collection<String> strings = new ArrayList<>(); + new Object() { + public void foo(String s) { + System.out.println( s.hashCode()); + } + }; + + for (String s : strings) { + System.out.println(<selection>s.hashCode()</selection>); + } + } + + +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceVariable/AnonymousClass5.after.java b/java/java-tests/testData/refactoring/introduceVariable/AnonymousClass5.after.java new file mode 100644 index 000000000000..9157c7896b91 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/AnonymousClass5.after.java @@ -0,0 +1,20 @@ + +import java.util.ArrayList; +import java.util.Collection; + +public class ExtractVariableSample { + + public static void main(String[] args, String s) { + Collection<String> strings = new ArrayList<>(); + new Object() { + public void foo(String s) { + System.out.println( s.hashCode()); + } + }; + + int j = s.hashCode(); + System.out.println(j); + } + + +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceVariable/AnonymousClass5.java b/java/java-tests/testData/refactoring/introduceVariable/AnonymousClass5.java new file mode 100644 index 000000000000..7e1bc3a0be91 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/AnonymousClass5.java @@ -0,0 +1,19 @@ + +import java.util.ArrayList; +import java.util.Collection; + +public class ExtractVariableSample { + + public static void main(String[] args, String s) { + Collection<String> strings = new ArrayList<>(); + new Object() { + public void foo(String s) { + System.out.println( s.hashCode()); + } + }; + + System.out.println(<selection>s.hashCode()</selection>); + } + + +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceVariable/Lambda.after.java b/java/java-tests/testData/refactoring/introduceVariable/Lambda.after.java new file mode 100644 index 000000000000..3d952827c70c --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/Lambda.after.java @@ -0,0 +1,22 @@ + +import java.util.ArrayList; +import java.util.Collection; + +public class ExtractVariableSample { + interface I { + void foo(String s); + } + + public static void main(String[] args) { + Collection<String> strings = new ArrayList<>(); + I i = (s) -> { + int j = s.hashCode(); + System.out.println(j); }; + + for (String s : strings) { + System.out.println(s.hashCode()); + } + } + + +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceVariable/Lambda.java b/java/java-tests/testData/refactoring/introduceVariable/Lambda.java new file mode 100644 index 000000000000..e331f2b10e23 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/Lambda.java @@ -0,0 +1,20 @@ + +import java.util.ArrayList; +import java.util.Collection; + +public class ExtractVariableSample { + interface I { + void foo(String s); + } + + public static void main(String[] args) { + Collection<String> strings = new ArrayList<>(); + I i = (s) -> { System.out.println(<selection>s.hashCode()</selection>); }; + + for (String s : strings) { + System.out.println(s.hashCode()); + } + } + + +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceVariable/SubLiteralFailure.java b/java/java-tests/testData/refactoring/introduceVariable/SubLiteralFailure.java new file mode 100644 index 000000000000..8eb2a45cde3f --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/SubLiteralFailure.java @@ -0,0 +1,5 @@ +class A { + public void test() { + int i = <selection>1</selection>23 + 123; + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/pullUp/PublicMethodFromPrivateClassConflict.java b/java/java-tests/testData/refactoring/pullUp/PublicMethodFromPrivateClassConflict.java new file mode 100644 index 000000000000..a028329a4693 --- /dev/null +++ b/java/java-tests/testData/refactoring/pullUp/PublicMethodFromPrivateClassConflict.java @@ -0,0 +1,9 @@ +import java.util.*; +class A {} +class B extends A { + void fo<caret>o() { + HM<String, String> hm = new HM<>(); + for (Map.Entry<String, String> stringStringEntry : hm.entrySet()) {} + } + private static class HM<K, V> extends HashMap<K, V>{} +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/pullUp/PublicMethodFromPrivateClassConflict_after.java b/java/java-tests/testData/refactoring/pullUp/PublicMethodFromPrivateClassConflict_after.java new file mode 100644 index 000000000000..96932a3c1923 --- /dev/null +++ b/java/java-tests/testData/refactoring/pullUp/PublicMethodFromPrivateClassConflict_after.java @@ -0,0 +1,11 @@ +import java.util.*; +class A { + void foo() { + HM<String, String> hm = new HM<>(); + for (Map.Entry<String, String> stringStringEntry : hm.entrySet()) {} + } + + private static class HM<K, V> extends HashMap<K, V>{} +} +class B extends A { +}
\ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/ParameterInfoTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/ParameterInfoTest.java index b31fb169cf33..2c757c1725b9 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/ParameterInfoTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/ParameterInfoTest.java @@ -10,6 +10,9 @@ import com.intellij.psi.*; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.testFramework.LightCodeInsightTestCase; import com.intellij.testFramework.utils.parameterInfo.MockCreateParameterInfoContext; +import com.intellij.testFramework.utils.parameterInfo.MockUpdateParameterInfoContext; +import com.intellij.util.ArrayUtil; +import com.intellij.util.ArrayUtilRt; import com.intellij.util.Function; import junit.framework.Assert; @@ -54,6 +57,35 @@ public class ParameterInfoTest extends LightCodeInsightTestCase { doTestPresentation("<html>List<String> param</html>"); } + public void testSelectionWithGenerics() throws Exception { + configureByFile(BASE_PATH + getTestName(false) + ".java"); + + final MethodParameterInfoHandler handler = new MethodParameterInfoHandler(); + final CreateParameterInfoContext context = new MockCreateParameterInfoContext(myEditor, myFile); + final PsiExpressionList list = handler.findElementForParameterInfo(context); + assertNotNull(list); + final Object[] itemsToShow = context.getItemsToShow(); + assertNotNull(itemsToShow); + assertTrue(itemsToShow.length == 2); + assertTrue(itemsToShow[0] instanceof MethodCandidateInfo); + final ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, myEditor, handler, -1); + final Boolean [] enabled = new Boolean[itemsToShow.length]; + final MockUpdateParameterInfoContext updateParameterInfoContext = new MockUpdateParameterInfoContext(myEditor, myFile){ + @Override + public Object[] getObjectsToView() { + return itemsToShow; + } + + @Override + public void setUIComponentEnabled(int index, boolean b) { + enabled[index] = b; + } + }; + updateParameterInfoContext.setParameterOwner(list); + handler.updateParameterInfo(list, updateParameterInfoContext); + assertTrue(ArrayUtilRt.find(enabled, Boolean.TRUE) > -1); + } + public void testAfterGenericsInsideCall() throws Exception { configureByFile(BASE_PATH + getTestName(false) + ".java"); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/HippieCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/HippieCompletionTest.groovy index ab9ea13a425d..669f0f53bed2 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/HippieCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/HippieCompletionTest.groovy @@ -36,16 +36,29 @@ $some_long_variable_name<caret> public void testFromAnotherFile() { myFixture.configureByText "b.txt", ''' -$some_long_variable_name = Obj::instance(); +$some_local = 1; ''' myFixture.configureByText "a.txt", ''' -$some_lon<caret> +$some_long_variable_name = Obj::instance(); +$some_lo<caret> ''' complete() myFixture.checkResult ''' +$some_long_variable_name = Obj::instance(); $some_long_variable_name<caret> ''' + complete() + myFixture.checkResult ''' +$some_long_variable_name = Obj::instance(); +$some_local<caret> +''' + backComplete() + myFixture.checkResult ''' +$some_long_variable_name = Obj::instance(); +$some_long_variable_name<caret> +''' + } public void "test no middle matching"() { @@ -128,7 +141,24 @@ class Xoo { } + public void "test file start"() { + myFixture.configureByText "a.java", '''<caret> +class Xoo { +} +''' + complete() + myFixture.checkResult '''class<caret> +class Xoo { +} +''' + + } + private void complete() { myFixture.performEditorAction(IdeActions.ACTION_HIPPIE_COMPLETION) } + + private void backComplete() { + myFixture.performEditorAction(IdeActions.ACTION_HIPPIE_BACKWARD_COMPLETION) + } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java index c386bd3c0f7a..72840250b795 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java @@ -17,6 +17,9 @@ package com.intellij.codeInsight.completion; import com.intellij.JavaTestUtil; import com.intellij.codeInsight.lookup.Lookup; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.impl.source.resolve.PsiResolveHelperImpl; +import com.intellij.psi.impl.source.resolve.graphInference.PsiGraphInferenceHelper; import com.intellij.testFramework.LightProjectDescriptor; import org.jetbrains.annotations.NotNull; @@ -70,6 +73,29 @@ public class SmartType18CompletionTest extends LightFixtureCompletionTestCase { doTest(); } + public void testFilteredMethodReference() throws Exception { + doTest(); + } + + public void testNotAvailableInLambdaPositionAfterQualifier() throws Exception { + configureByFile("/" + getTestName(false) + ".java"); + assertNotNull(myItems); + assertTrue(myItems.length == 0); + } + + public void testInferFromRawType() throws Exception { + final PsiResolveHelperImpl helper = (PsiResolveHelperImpl)JavaPsiFacade.getInstance(getProject()).getResolveHelper(); + helper.setTestHelper(new PsiGraphInferenceHelper(getPsiManager())); + try { + configureByFile("/" + getTestName(false) + ".java"); + assertNotNull(myItems); + assertTrue(myItems.length == 0); + } + finally { + helper.setTestHelper(null); + } + } + private void doTest() { configureByFile("/" + getTestName(false) + ".java"); assertNotNull(myItems); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java index 9d7673d770f5..64798f400e06 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -332,6 +332,8 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testIDEA65377() { doTest5(false); } public void testIDEA113526() { doTest5(true); } public void testIDEA116493() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } + public void testIDEA117827() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } + public void testIDEA118037() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testJavaUtilCollections_NoVerify() throws Exception { PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule())); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Diamond8HighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Diamond8HighlightingTest.java index 99c7c27b9dbc..ca4133b79172 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Diamond8HighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Diamond8HighlightingTest.java @@ -16,6 +16,8 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; public class Diamond8HighlightingTest extends LightDaemonAnalyzerTestCase { @@ -25,7 +27,16 @@ public class Diamond8HighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testOuterClass() throws Exception { + doTest(); + } + private void doTest() throws Exception { doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", false, false); } + + @Override + protected Sdk getProjectJDK() { + return IdeaTestUtil.getMockJdk18(); + } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java index 964dca8b8e04..34ae397e1464 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java @@ -44,7 +44,7 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase { @Override protected Sdk getProjectJDK() { - return getTestName(false).contains("Jdk14") ? IdeaTestUtil.getMockJdk14() : super.getProjectJDK(); + return IdeaTestUtil.getMockJdk18(); } public void testReferenceTypeParams() { @@ -762,19 +762,4 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase { doTest(); } - public void testJavaUtilCollections_NoVerify() throws Exception { - PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule())); - assertNotNull(collectionsClass); - collectionsClass = (PsiClass)collectionsClass.getNavigationElement(); - final String text = collectionsClass.getContainingFile().getText(); - configureFromFileText("Collections.java", text.replaceAll("\r", "\n")); - final PsiResolveHelperImpl helper = (PsiResolveHelperImpl)JavaPsiFacade.getInstance(getProject()).getResolveHelper(); - helper.setTestHelper(new PsiGraphInferenceHelper(getPsiManager())); - try { - doTestConfiguredFile(false, false, null); - } - finally { - helper.setTestHelper(null); - } - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java index dee913755ead..d0048b7f962f 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java @@ -17,6 +17,7 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.openapi.projectRoots.JavaSdkVersion; +import com.intellij.openapi.projectRoots.Sdk; import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; @@ -115,4 +116,9 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable()); doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false); } + + @Override + protected Sdk getProjectJDK() { + return IdeaTestUtil.getMockJdk18(); + } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java index 4a0851a3bbe9..8e43934432aa 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java @@ -18,6 +18,8 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -103,4 +105,9 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase { private void doTest(final boolean checkWarnings) { doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false); } + + @Override + protected Sdk getProjectJDK() { + return IdeaTestUtil.getMockJdk18(); + } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java index c0fed3d47911..7c25d3b43c05 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java @@ -19,6 +19,7 @@ import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; import com.intellij.openapi.projectRoots.JavaSdkVersion; +import com.intellij.openapi.projectRoots.Sdk; import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -101,4 +102,9 @@ public class MethodRefHighlightingTest extends LightDaemonAnalyzerTestCase { IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable()); doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", warnings, false); } + + @Override + protected Sdk getProjectJDK() { + return IdeaTestUtil.getMockJdk18(); + } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java index 34a45ee3e094..35b91ef35f26 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java @@ -19,6 +19,7 @@ import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; import com.intellij.openapi.projectRoots.JavaSdkVersion; +import com.intellij.openapi.projectRoots.Sdk; import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -82,6 +83,18 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testArgumentOfAnonymousClass() throws Exception { + doTest(); + } + + public void testEllipsis() throws Exception { + doTest(); + } + + public void testOuterMethodPropagation() throws Exception { + doTest(); + } + private void doTest() { doTest(false); } @@ -90,4 +103,9 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase { IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable()); doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", warnings, false); } + + @Override + protected Sdk getProjectJDK() { + return IdeaTestUtil.getMockJdk18(); + } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java index ae3df006df09..80d2e4ac2fb6 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java @@ -72,6 +72,10 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase { doTestField(); } + public void testCode() throws Exception { + doTestField(); + } + public void testEnumConstantOrdinal() throws Exception { PsiClass psiClass = getTestClass(); PsiField field = psiClass.getFields() [0]; diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspection8Test.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspection8Test.java index 0e7d62016f42..0a7b46aa507a 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspection8Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspection8Test.java @@ -45,6 +45,14 @@ public class DataFlowInspection8Test extends LightCodeInsightFixtureTestCase { doTest(); } + public void testReturnNullInLambdaExpression() throws Exception { + doTest(); + } + + public void testReturnNullInLambdaStatement() throws Exception { + doTest(); + } + private void setupCustomAnnotations() { myFixture.addClass("package foo;\n\nimport java.lang.annotation.*;\n\n@Target({ElementType.TYPE_USE}) public @interface Nullable { }"); myFixture.addClass("package foo;\n\nimport java.lang.annotation.*;\n\n@Target({ElementType.TYPE_USE}) public @interface NotNull { }"); diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/LocalCanBeFinalTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/LocalCanBeFinalTest.java index e29b65c31bcc..61895f6cb132 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/LocalCanBeFinalTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/LocalCanBeFinalTest.java @@ -127,12 +127,14 @@ public class LocalCanBeFinalTest extends InspectionTestCase { public void testForeachNotReported() throws Exception { myTool.REPORT_PARAMETERS = true; myTool.REPORT_VARIABLES = false; + myTool.REPORT_FOREACH_PARAMETERS = false; doTest(); } public void testNestedForeach() throws Exception { myTool.REPORT_PARAMETERS = false; myTool.REPORT_VARIABLES = true; + myTool.REPORT_FOREACH_PARAMETERS = true; doTest(); } diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast15Test.java b/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast15Test.java index 91afe58145b7..ca3065d27d14 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast15Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast15Test.java @@ -50,6 +50,7 @@ public class RedundantCast15Test extends InspectionTestCase { public void testInstanceOfChecks() throws Exception { doTest();} public void testForEachValue() throws Exception { doTest();} public void testCaseThrowable() throws Exception { doTest();} + public void testSafeTempVarName() throws Exception { doTest();} public void testTypeParameterAccessChecksJava7() throws Exception { IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_7, getModule(), getTestRootDisposable()); diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/RedundantTypeArgsInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/RedundantTypeArgsInspectionTest.java index 53aba55cf689..c3c092c0b663 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/RedundantTypeArgsInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/RedundantTypeArgsInspectionTest.java @@ -37,4 +37,8 @@ public class RedundantTypeArgsInspectionTest extends JavaCodeInsightFixtureTestC public void testBoundInference() throws Throwable { doTest(); } + + public void testNestedCalls() throws Throwable { + doTest(); + } }
\ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/ide/hierarchy/JavaCallHierarchyTest.java b/java/java-tests/testSrc/com/intellij/ide/hierarchy/JavaCallHierarchyTest.java index aebc9e00bd9b..fcdad698aedd 100644 --- a/java/java-tests/testSrc/com/intellij/ide/hierarchy/JavaCallHierarchyTest.java +++ b/java/java-tests/testSrc/com/intellij/ide/hierarchy/JavaCallHierarchyTest.java @@ -1,12 +1,15 @@ package com.intellij.ide.hierarchy; import com.intellij.JavaTestUtil; +import com.intellij.ide.hierarchy.actions.BrowseTypeHierarchyAction; import com.intellij.ide.hierarchy.call.CallerMethodsTreeStructure; +import com.intellij.ide.highlighter.XmlFileType; import com.intellij.openapi.util.Computable; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiMethod; import com.intellij.psi.search.ProjectScope; +import com.intellij.testFramework.TestActionEvent; import com.intellij.testFramework.codeInsight.hierarchy.HierarchyViewTestBase; /** @@ -53,4 +56,12 @@ public class JavaCallHierarchyTest extends HierarchyViewTestBase { public void testIdeaDev41232() throws Exception { doJavaCallTypeHierarchyTest("A", "main", "B.java", "A.java"); } + + public void testActionAvailableInXml() throws Exception { + configureByText(XmlFileType.INSTANCE, "<foo>java.lang.Str<caret>ing</foo>"); + BrowseTypeHierarchyAction action = new BrowseTypeHierarchyAction(); + TestActionEvent e = new TestActionEvent(action); + action.beforeActionPerformedUpdate(e); + assertTrue(e.getPresentation().isEnabled() && e.getPresentation().isVisible()); + } } diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerBlankLinesTest.groovy b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerBlankLinesTest.groovy index b456d41aa300..8f64026800ac 100644 --- a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerBlankLinesTest.groovy +++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerBlankLinesTest.groovy @@ -24,6 +24,14 @@ import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Mo */ public class JavaRearrangerBlankLinesTest extends AbstractJavaRearrangerTest { + def classic = [rule(INTERFACE), + rule(CLASS), + rule(FIELD, STATIC), + rule(FIELD, PUBLIC), + rule(FIELD), + rule(METHOD, PUBLIC), + rule(METHOD)] + void testPreserveRelativeBlankLines() { commonSettings.BLANK_LINES_AROUND_CLASS = 2 commonSettings.BLANK_LINES_AROUND_FIELD = 1 @@ -78,13 +86,7 @@ class Test { private void method1() {} }''', - rules: [rule(INTERFACE), - rule(CLASS), - rule(FIELD, STATIC), - rule(FIELD, PUBLIC), - rule(FIELD), - rule(METHOD, PUBLIC), - rule(METHOD)] + rules: classic ) } @@ -143,4 +145,64 @@ public enum Sender {a, b; private String value; doTest(initial: before, expected: before) } + + + void "test keep blank lines between fields"() { + def text = '''\ +public class Test { + private static final Logger LOGGER = LoggerFactory.getLogger(AddCurrentUser.class); + + + private GlobalQueryService globalQueryService; + private EventCoordinationService eventCoordinationService; +} +''' + doTest( + initial: text, + expected: text, + rules: classic + ) + } + + void "test keep blank lines between fields more fair test"() { + doTest( + initial: '''\ +public class Test { + private static final int t = 12; + + + public int q = 2; + private int e = 3; + public int t11 = 23; + + private void test() { + } + + public void main() { + } + +} +''', + expected: '''\ +public class Test { + private static final int t = 12; + + + public int q = 2; + public int t11 = 23; + private int e = 3; + + public void main() { + } + + private void test() { + } + +} +''', + rules: classic + ) + } + + } diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFieldReferenceTest.groovy b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFieldReferenceTest.groovy new file mode 100644 index 000000000000..a2a996a36048 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFieldReferenceTest.groovy @@ -0,0 +1,256 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.codeStyle.arrangement + +import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule + +import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.EntryType.*; +import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Modifier.*; + +class JavaRearrangerFieldReferenceTest extends AbstractJavaRearrangerTest { + + private List<StdArrangementMatchRule> defaultFieldsArrangement = [ + rule(CLASS), + rule(FIELD, PUBLIC), + rule(FIELD, PROTECTED), + rule(FIELD, PACKAGE_PRIVATE), + rule(FIELD, PRIVATE) + ] + + + void "test keep referenced package private field before public one which has reference through binary expression"() { + doTest(initial: '''\ +public class TestRunnable { + int i = 1; + public int j = i + 1; + public int k = 3; + public int m = 23; +} +''', + expected: '''\ +public class TestRunnable { + public int k = 3; + public int m = 23; + int i = 1; + public int j = i + 1; +} +''', + rules: defaultFieldsArrangement + ); + } + + void "test keep referenced fields before those who has reference through binary expression"() { + doTest(initial: '''\ +public class javaTest { + int i1 = 1; + protected int i2 = i1 + 4; +} +''', + expected: '''\ +public class javaTest { + int i1 = 1; + protected int i2 = i1 + 4; +} +''', + rules: defaultFieldsArrangement + ); + } + + void "test keep referenced static fields before those who has reference through binary expression"() { + doTest(initial: '''\ +public class CodeFormatTest { + private static String PREFIX = "prefix."; + public static String NAME = PREFIX + "name"; + private static String PRIVATE_NAME = PREFIX + "private name"; + public static String TEST = "OK!"; + public static String BOOK = "ATLAS"; +} +''', + expected: '''\ +public class CodeFormatTest { + public static String TEST = "OK!"; + public static String BOOK = "ATLAS"; + private static String PREFIX = "prefix."; + private static String PRIVATE_NAME = PREFIX + "private name"; + public static String NAME = PREFIX + "name"; +} +''', + rules: defaultFieldsArrangement + ); + } + + void "test keep referenced static fields before those who has direct reference"() { + doTest(initial: '''\ +public class CodeFormatTest { + private static String PREFIX = "prefix."; + public static String NAME = PREFIX; +} +''', + expected: '''\ +public class CodeFormatTest { + private static String PREFIX = "prefix."; + public static String NAME = PREFIX; +} +''', + rules: defaultFieldsArrangement + ); + } + + void "test keep referenced fields before those who has direct reference"() { + doTest(initial: '''\ +public class CodeFormatTest { + private String PREFIX = "prefix."; + public String NAME = PREFIX; +} +''', + expected: '''\ +public class CodeFormatTest { + private String PREFIX = "prefix."; + public String NAME = PREFIX; +} +''', + rules: defaultFieldsArrangement + ); + } + + void "test keep referenced fields before those who has reference through polyadic expression"() { + doTest(initial: '''\ +public class CodeFormatTest { + private String PREFIX = "prefix."; + public String NAME = "ololo" + "bobob" + "line" + PREFIX + "ququ"; +} +''', + expected: '''\ +public class CodeFormatTest { + private String PREFIX = "prefix."; + public String NAME = "ololo" + "bobob" + "line" + PREFIX + "ququ"; +} +''', + rules: defaultFieldsArrangement + ); + } + + void "test keep referenced field before who has reference through parenthesized nested binary expression"() { + doTest(initial: '''\ +public class TestRunnable { + int i = 3; + public int j = (1 + i); +} +''', + expected: '''\ +public class TestRunnable { + int i = 3; + public int j = (1 + i); +} +''', + rules: defaultFieldsArrangement + ); + } + + + + void "test keep referenced fields before those who has reference through nested binary expression"() { + doTest(initial: '''\ +public class TestRunnable { + int i = 3; + public int j = (1 + 2 + (5 + (5 + (5 + i))) + (1 + (i + 1)) + (3 + i) + 5) + 4; +} +''', + expected: '''\ +public class TestRunnable { + int i = 3; + public int j = (1 + 2 + (5 + (5 + (5 + i))) + (1 + (i + 1)) + (3 + i) + 5) + 4; +} +''', + rules: defaultFieldsArrangement + ); + } + + + void "test multiple references on instance fields"() { + doTest(initial: '''\ +public class TestRunnable { + int i = 3; + int k = 12; + public int j = (1 + 2 + (5 + (5 + (5 + i))) + (1 + (i + 1 + k)) + (3 + i) + 5) + 4; + public int q = 64; +} +''', + expected: '''\ +public class TestRunnable { + public int q = 64; + int i = 3; + int k = 12; + public int j = (1 + 2 + (5 + (5 + (5 + i))) + (1 + (i + 1 + k)) + (3 + i) + 5) + 4; +} +''', + rules: defaultFieldsArrangement + ); + } + + + void "test field initializer has reference to method"() { + doTest(initial: '''\ +public class TestRunnable { + public int foo() { + return 15; + } + + public int q = 64 + foo(); + int i = 3; + int k = 12; +} +''', + expected: '''\ +public class TestRunnable { + public int q = 64 + foo(); + int i = 3; + int k = 12; + + public int foo() { + return 15; + } +} +''', + rules: [rule(CLASS), + rule(FIELD, PUBLIC), + rule(FIELD, PACKAGE_PRIVATE), + rule(METHOD, PUBLIC)] + ) + } + + void "test illegal field reference arranged to legal"() { + doTest(initial: '''\ +public class Alfa { + int i = 3; + public int j = i + 1 + q; + int q = 2 + 3; + public int r = 3; +} +''', + expected: '''\ +public class Alfa { + public int r = 3; + int i = 3; + int q = 2 + 3; + public int j = i + 1 + q; +} +''', + rules: defaultFieldsArrangement + ); + } + +} diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterInEditorTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterInEditorTest.java index 7355feba87e3..ed79f2f60bc6 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterInEditorTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterInEditorTest.java @@ -97,6 +97,39 @@ public class JavaFormatterInEditorTest extends LightPlatformCodeInsightTestCase doTest(before, after); } + public void testCaretLineAndPositionPreserved_WhenBracketOnNextLineWillBeFormatted() throws IOException { + String before = "public class Test {\n" + + " int a;\n" + + " \n" + + " public static void main(String[] args) {\n" + + " <caret>\n" + + " }\n" + + "\n" + + " static final long j = 2;\n" + + "}"; + String after = "public class Test {\n" + + " int a;\n" + + "\n" + + " public static void main(String[] args) {\n" + + " <caret>\n" + + " }\n" + + "\n" + + " static final long j = 2;\n" + + "}"; + doTest(before, after); + + before = "public class Test {\n" + + " int a;\n" + + " \n" + + " public static void main(String[] args) {\n" + + " <caret> \n" + + " }\n" + + "\n" + + " static final long j = 2;\n" + + "}"; + doTest(before, after); + } + public void doTest(@NotNull String before, @NotNull String after) throws IOException { configureFromFileText(getTestName(false) + ".java", before); CodeStyleManager.getInstance(getProject()).reformatText(getFile(), 0, getEditor().getDocument().getTextLength()); diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java index 4cedbc31e52f..8adb06b24d19 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java @@ -3004,6 +3004,7 @@ public void testSCR260() throws Exception { public void testFormatterOnOffTags() throws Exception { getSettings().getRootSettings().FORMATTER_TAGS_ENABLED = true; + getSettings().IF_BRACE_FORCE = CommonCodeStyleSettings.FORCE_BRACES_ALWAYS; doTest(); } diff --git a/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveMethod15Test.java b/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveMethod15Test.java index 36b1c4c9de63..788febf4da6e 100644 --- a/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveMethod15Test.java +++ b/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveMethod15Test.java @@ -7,7 +7,6 @@ import com.intellij.navigation.NavigationItem; import org.jetbrains.annotations.NonNls; import static org.junit.Assert.assertThat; import static org.hamcrest.core.IsInstanceOf.instanceOf; -import static org.junit.Assert.assertTrue; /** * @author dsl @@ -129,6 +128,16 @@ public class ResolveMethod15Test extends Resolve15TestCase { assertTrue(containingClass != null ? containingClass.getName() : null, containingClass instanceof PsiAnonymousClass); } + public void testCovariantReturnTypeAnonymous() throws Exception { + final PsiReference ref = configureByFile(); + assertThat(ref, instanceOf(PsiReferenceExpression.class)); + final PsiReferenceExpression refExpr = (PsiReferenceExpression)ref; + final PsiElement resolve = refExpr.resolve(); + assertTrue(resolve != null ? resolve.toString() : null, resolve instanceof PsiMethod); + final PsiClass containingClass = ((PsiMethod)resolve).getContainingClass(); + assertTrue(containingClass != null ? containingClass.getName() : null, !(containingClass instanceof PsiAnonymousClass)); + } + public void testFilterFixedVsVarargs1() throws Exception { final PsiReference ref = configureByFile(); assertThat(ref, instanceOf(PsiReferenceExpression.class)); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java index 07f3a61f96ed..35560bf18b12 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java @@ -78,6 +78,22 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase { doTest(new MockIntroduceVariableHandler("j", true, false, false, "int")); } + public void testAnonymousClass3() throws Exception { + doTest(new MockIntroduceVariableHandler("j", true, false, false, "Foo")); + } + + public void testAnonymousClass4() throws Exception { + doTest(new MockIntroduceVariableHandler("j", true, false, false, "int")); + } + + public void testAnonymousClass5() throws Exception { + doTest(new MockIntroduceVariableHandler("j", true, false, false, "int")); + } + + public void testLambda() throws Exception { + doTest(new MockIntroduceVariableHandler("j", true, false, false, "int")); + } + public void testParenthized() throws Exception { doTest(new MockIntroduceVariableHandler("temp", true, false, false, "int")); } @@ -208,6 +224,18 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase { doTest(new MockIntroduceVariableHandler("str", false, false, false, "java.lang.String")); } + public void testSubLiteralFailure() throws Exception { + try { + doTest(new MockIntroduceVariableHandler("str", false, false, false, "int")); + } + catch (Exception e) { + assertEquals(e.getMessage(), "Error message:Cannot perform refactoring.\n" + + "Selected block should represent an expression"); + return; + } + fail("Should not be able to perform refactoring"); + } + public void testSubLiteralFromExpression() throws Exception { doTest(new MockIntroduceVariableHandler("str", false, false, false, "java.lang.String")); } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java b/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java index aa539bd4d801..cbf095578213 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java @@ -147,6 +147,10 @@ public class PullUpTest extends LightRefactoringTestCase { doTest(false, new RefactoringTestUtil.MemberDescriptor("foo", PsiMethod.class)); } + public void testPublicMethodFromPrivateClassConflict() { + doTest(false, new RefactoringTestUtil.MemberDescriptor("HM", PsiClass.class), new RefactoringTestUtil.MemberDescriptor("foo", PsiMethod.class)); + } + private void doTest(RefactoringTestUtil.MemberDescriptor... membersToFind) { doTest(true, membersToFind); } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineParameterTest.java index 29d85f134314..b49a306ccedd 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineParameterTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineParameterTest.java @@ -134,6 +134,10 @@ public class InlineParameterTest extends LightRefactoringTestCase { doTest(true); } + public void testFromClassInitializer() throws Exception { + doTest(false); + } + public void testParameterWithWriteAccess() throws Exception { try { doTest(false); diff --git a/java/mockJDK-1.7/jre/lib/rt.jar b/java/mockJDK-1.7/jre/lib/rt.jar Binary files differindex 3a3995e2d9cf..83d84402c386 100644 --- a/java/mockJDK-1.7/jre/lib/rt.jar +++ b/java/mockJDK-1.7/jre/lib/rt.jar diff --git a/java/mockJDK-1.8/jre/lib/rt.jar b/java/mockJDK-1.8/jre/lib/rt.jar Binary files differnew file mode 100644 index 000000000000..db566fc40076 --- /dev/null +++ b/java/mockJDK-1.8/jre/lib/rt.jar diff --git a/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java b/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java index eb378f128a78..e0a2806d4668 100644 --- a/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java +++ b/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java @@ -77,6 +77,10 @@ public class IdeaTestUtil extends PlatformTestUtil { return JavaSdk.getInstance().createJdk(name, getMockJdk17Path().getPath(), false); } + public static Sdk getMockJdk18() { + return JavaSdk.getInstance().createJdk("java 1.8", getMockJdk18Path().getPath(), false); + } + public static Sdk getMockJdk14() { return JavaSdk.getInstance().createJdk("java 1.4", getMockJdk14Path().getPath(), false); } @@ -89,6 +93,10 @@ public class IdeaTestUtil extends PlatformTestUtil { return getPathForJdkNamed("mockJDK-1.7"); } + public static File getMockJdk18Path() { + return getPathForJdkNamed("mockJDK-1.8"); + } + private static File getPathForJdkNamed(String name) { File mockJdkCEPath = new File(PathManager.getHomePath(), "java/" + name); return mockJdkCEPath.exists() ? mockJdkCEPath : new File(PathManager.getHomePath(), "community/java/" + name); @@ -130,4 +138,6 @@ public class IdeaTestUtil extends PlatformTestUtil { } }); } + + } |