diff options
author | Tor Norbye <tnorbye@google.com> | 2014-03-10 13:13:45 -0700 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2014-03-10 13:13:51 -0700 |
commit | 1fff8e2b7bbcfdea262d3782d4307ca6437da2a3 (patch) | |
tree | 2709e256856c1d80b5cf344b7b0c292a756a2842 /java | |
parent | 88f318c9bf709fa5700350636925f2c46d6ae08d (diff) | |
download | idea-1fff8e2b7bbcfdea262d3782d4307ca6437da2a3.tar.gz |
Snapshot ae49fc0ed43dd87b534931e62fceae2bcac4fdf1 from idea/134.1445 of git://git.jetbrains.org/idea/community.gitsnapshot-master
ae49fc0: scala 0.32.(593|562|558|550) and AngularJS 0.1.(8|9) marked as incompatible
c3a2e25: Remove unused variable
fe44c93: Multicaret XML: fix type handler for multicaret mode
94108b1: IDEA-121711 Breakpoints dialog: cannot select items in Field Watchpoints section
4933fb4: Add AngularJS plugin
c0ee8f0: IntelliJ Idea 13.1 artworks
95977a0: new inference: cleanup
b3b99f4: ensure order
e9d3421: update button on installed plugins panel
5237f29: IDEA-121151 Breakpoints dialog: Group by Package / File shows exception items in wrong branch
6289c57: show information about multiple carets in status bar (IDEA-80056)
9ac9b91: add getCaretCount method to caret model API (IDEA-80056)
37b836c: WEB-11122 we cannot trust editor width — it could be 0 in case of soft wrap even if editor has text
ad2e3a9: nashorn: frames view — correct presentation of stack frame (function name is not yet displayed)
35fd0fc: cleanup
a433603: Use new icons and fgs
f9e15e0: CPP-6: Parameter info highlighting is messed up + review CR-IC-4631
d158a03: editorPaintStart useless in our case
d22cffe: don't paint in the overlapped region
3181d9a: CR-IC-4638 EvaluateInConsoleFromTreeAction
aa9d729: refactoring branch actions
367266a: style: sort hg reference names in getNamesWithoutHashes, unnecessary ui model creation removed
f0aba00: style: ternary operator used instead of several if-statements; comment added; unnecessary pool thread removed
58d9042: IDEA-121096 The ability to delete Mercurial bookmark
1a11673: IDEA-109794 ability to push mercurial bookmark
e4edbe9: hg action dialog refactoring
d61ace7: optimization broke code (IDEA-118426)
0da53a2: add new plugins icons
fe4a2a0: plugin update icon
9f5335b: plugin restart icon
24aab3b: plugin icon with JB logo
43e5b58: IDEA-121589 Breakpoints dialog: breakpoint categories should be present in a fixed order
f1f1141: IDEA-121675 Nashorn: Debug: RunToCursor is always disabled when js file is active
5b29ebf: Merge remote-tracking branch 'origin/master'
6893d29: revert
21068c7: scene builder: embedder
14de5df: Merge branch 'python-fixes'
7a968d0: IDEA-121642 Breakpoints dialog: closing "Disabled until" hides preview
b3a39df: caret listeners API change (IDEA-80056)
d98f5f7: IDEA-103517 diff: fix diff invocation from history tab
de02a90: revert incorrect change: BuildManager was not notified about files changes at all
e3f3e5f: notnull
6b3a754: cleanup
39bfb97: notnull
0fdd39a: CAPACITY inlined
337138e: CR-IC-4638 we must use "XDebugger", but not "Debugger"
1f2dd56: cleanup
33b0145: IDEA-121675 Nashorn: Debug: RunToCursor is always disabled when js file is active
f4d0239: fix exception at completion when multiple carets are enabled (IDEA-80056)
bc22d75: Compare sys.path roots by virtual file, not by filename because of *.egg archives
90bd285: Extracted getSdkRootVirtualFile()
0eab6fd: test framework: refresh module file
0c1cf4d: Cleanup (pointless exceptions; field extracted; arrangement)
b5a2bae: Cleanup (unused class)
5455508: Cleanup (pointless exceptions dropped)
bc72137: cleanup
3ff0739: NotNull
911290e: cleanup
b770509: cleanup
7d78ad3: cleanup
effe895: cleanup
126f4a0: cleanup
0e49f4a: anonymous -> lambda/method ref: highlight as unused symbol new ClassReference
9860e6b: migration inspection: assign weak warning to produce annoyance
380c7a9: testdata for IDEA-121661
0fa7d08: IDEA-121658 Java 1.8: "Replace with forEach" quick fix is not suggested if for statement is not surrounded with braces
c692398: Local History change temporarily reverted
803d865: IDEA-121640 Breakpoints conversion: conditions and log message languages all turn to Java
d1194fb: IDEA-121643 Breakpoints conversion: exception breakpoint dependencies are lost
95069e7: IDEA-121644 Breakpoints conversion: wildcard method breakpoints get Method entry = Method exit = true
02387b0: IDEA-121632 DomStubBuilder#getStubVersion does not use DomFileDescription#getStubVersion
01a42e5: IDEA-121632 DomStubBuilder#getStubVersion does not use DomFileDescription#getStubVersion
d05d6cd: IDEA-121555 github: get host from url before comparison
314a555: Storyboard format
8181cdb: IDEA-82129 diff: fix synchronized scrolling in merge dialog for left-middle panels
7d76faf: diff: replace Pair by container class
6baec97: repeatCount mostly done
9f2cf02: cleanup — inline
5ff9d4f: improvements for multi-caret implementation of column mode (IDEA-80056)
46208da: EA-53845 added logging
fdecf55: IDEA-121409, IDEA-120908 revert GrReassignedInClosureLocalVariableInspection back to previous state. So it doesn't check plain assignments to locals
9b9ffdb: Merge branch 'master' of git.labs.intellij.net:idea/community
f2d2e79: IDEA-120027 - Import Git-cloud apps from sources - refactor out account selection panel
121f738: IDEA-120027 - Import Git-cloud apps from sources - refactor out deployment detector
989fa1b: IDEA-121635 Injected fragment editor fails with \r\n in text
cc11811: Fix cloning sdk additional data.
7cfb673: Merge remote-tracking branch 'origin/master'
f30ac9d: Merge remote-tracking branch 'origin/master'
e31638a: IDEA-121621 Java 1.8: "Replace with collect" quick fix inserts unresolved method reference
1ae653c: Fix update of terminal input action wrapper.
fb14201: IDEA-116760 Mousing over "tool popup" button causes funny behavior
ece8311: file and doc mod stamps should be equal after save
e30e9ff: EA-53865 - assert: CachedValueProvider$Result.<init>
b5deb1d: Merge remote-tracking branch 'origin/master'
94ae901: PY-12178 Support pull up / push down for properties
27fb3a4: Local History fix: load file children on fileCreated event
5de8d20: a test for IDEA-121301 Setting a breakpoint after navigation to a folded method
a337747: use origin fqn
2a60f15: support ColorUIResource
16fa597: Merge remote-tracking branch 'origin/master'
6dd7d9d: parameter info: proper highlighting for text with XML escaped chars, e.g "map<string, int> &x" +review CR-IC
a3141a4: Merge branch 'python-fixes'
c6947e3: IDEA-108454 (test added)
7ba0d53: Merge remote-tracking branch 'origin/master'
5b6bfba: Disable default breakpoints in env debugger tests.
de2bcc9: Better logging in debugger communication.
f65481f: ResumeAction -> DumbAware
5312f17: IDEA-121301 Setting a breakpoint after navigation to a folded method
b82ea0b: updater: use system look&feel
76b0d68: CR-IU-615 (reworked)
09d9083: WI-22345 Fragment editor: typing causes Throwable at CompletionAssertions.assertCommitSuccessful()
65e4c34: Merge remote-tracking branch 'origin/master'
53752af: fixed PY-12321 PyCharm fails to auto-complete inherited PyQt methods
93eaeb4: Merge remote-tracking branch 'origin/master'
0a93c40: IDEA-121551 please sign runnerw.exe and commit
ec8c8eb: Breakpoint remove should be executed in write action like breakpoint add in XDebuggerTestUtil.
49a5a3f: don't duplicate symlink in suggested interpreter path
f673815: Fix creation of remote sdk in tests.
7a6a957: fix entities resolve without root tag
bd73c79: completion for html5 entities without root tag
41aaf52: #WEB-11032 fixed
9483000: external build: added API to allow plugins extend external build launcher classpath
465090e: Storyboard format
53d95f8: fetch commandLine from processHandler instance if possible
329b1a7: Merge remote-tracking branch 'origin/master'
dd2e76a: PY-12178 Support pull up / push down for properties
550a7e4: EvaluateInConsole
62cf3bb: ActionUtil.getActions
b01a8f1: use SmartList
f95d39d: Merge remote-tracking branch 'origin/master'
b7dca13: added browse interpreter button to create virtual env dialog
64fccff: IDEA-121378 Groovy: inspections: Access to untyped expression reports this and super
1b0f4e8: IDEA-121420 ctrl+b on "def" keyword of a variable without explicit type with initializer should navigate to inferred type
ed39848: IDEA-121140 format spock tables in the end of a file
f2fea0a: external build: added API to prepare custom java compilation task and provide default options for java compiler
0203ec8: Merge remote-tracking branch 'origin/master'
5acf645: Merge remote-tracking branch 'origin/master'
18dbd58: Merge remote-tracking branch 'origin/master'
f8f3d97: lambda: do not try to annotate super method with Nullable from lambda body (IDEA-120205) annotation for super methods was removed by cdr
a4977be: lambda/method refs: provide super class navigation - ctrl-u/line markers (IDEA-120160)
f1dac13: Deprecated remote sdk api. Old legacy classes leaved for compatibility.
4a4d94f: Merge remote-tracking branch 'origin/master'
59525f3: prepared copy of log4j before exec updater to avoid similar issue: WEB-11207 Patch to 8.0 build 134.1361 fails on Win 8.1
179bdc5: support null-values
fe93f3f: Query only the first result of super and overring method searches for performance resaons
6b1189e: more diagnostics for EA-50865 - assert: CachedValueProvider$Result.<init>
5396644: IDEA-121387 Breakpoints dialog: Exception breakpoints: no language chooser for Condition
279b7c3: EA-52976 - assert: CodeFoldingManagerImpl.releaseFoldings
00dbd95: Reuse resolve context with type eval context from the current inspection session for performance reasons
5313d0b: WI-14345 Dictionary: Missing Word "Fundraising"
f4d98a3: IDEA-121505 Breakpoint properties popup: More link does not work if over tool window splitter
fa27e1a: IDEA-121508 Breakpoints in JSP scriptlets are ignored
957b622: CR-IC-4621 allow evaluation in global context (without suspend context)
363a27a: overrides
9ef0155: finalize
ad6c95a: cleanup — move DisabledActionHandler to platform +review
e98cb45: cleanup
19adc49: cleanup
539e45a: Multicaret: fix tests
ede0620: fixed memory leak
6b8002e: Cache return types of callables using TypeEvalContext.getReturnType()
9ca3e42: IDEA-121582 (less spam in log)
b9b76dc: java: type annotations
b428981: java: shorten references after refactoring
d728fd7: IDEA-121518 Cannot edit files in IDEA after project opening: initial folding in opening thread, assertions relaxed
5ed9d91: better diagnostics
b1ae53c: javadoc
2691cb0: external build: ignore irrelevant messages in stderr of javac server (e.g. warnings from log4j)
a487452: continue WEB-10187 inspect objects in console
1a5af0d: more correct and concrete javadoc — it is NOT text, it is just highlighting
fc8c136: IDEA-121531 False positive for "Named arguments are not allowed inside index operations"
7a0eff4: external build: extracted extension point to support custom java compilers
0c6f4d1: don't display expanders on disabled components
c34a068: Merge remote-tracking branch 'origin/master'
a71ff7a: Propose to launch vagrant instance on connection to non-running vagrant remote host (PY-8751).
2905258: NotNull annotation for parent component
ea5f0a5: no "loading components" progress for default project
80d6e1f: new inference: use site substitutor during return constraints processing (red code in Collectors)
b55527a: testdata for IDEA-118965
0cb0127: IDEA-121379 ("Remove braces from if statement" is not available on "if" keyword and condition of if-else construct)
2e88d04: revert optimization because it does not optimize
d4883f5: rebuild list on EDT only
139374a: quick evaluate should allow evaluation in global context (without suspend context)
9051157: cleanup
3419368: init WEB-10187 inspect objects in console
14490aa: overrides
f9eaaef: IDEA-115491 Fragment editor > Save as: provide default directory
a2007d9: IDEA-115490 Fragment editor > Save as: forbidden default name
282ebd2: FormatterTestCase should be available to plugin developers
c4ee509: IDEA-121553 Converted field and exception breakpoints are not available to user
60dfeb6: EA-41231 (better diagnostic)
cec4bb0: show options in create new project instead of show dialog
851c599: fix highlighter update on FileContentUtil.reparseFiles()
842cb01: avoid PSI tree change listener leaks in breakpoint popup
7e61326: avoid PSI tree change listener leaks
a445e2c: table greyer (ability to disable a table)
dff15af: IDEA-105047 Map help button and F1 of the Breakpoints dialog
06fbfa3: WEB-11122 LiveConsole: do not hide input/output
e7ed9a2: cleanup use EditorUtil.scrollToTheEnd
2b22f1a: IDEA-121445 Incomplete breakpoint background highlighting
6cb7fe8: use SmartList
132c8d9: cleanup
34499ed: cleanup
9f501ce: Merge remote-tracking branch 'origin/master'
bbb835a: IDEA-121530 New Mac Messages: 'Invalidate caches' message (with 4 buttons) has one button cut off - First part. The message should be re-layouted. Currently, where is an empty space in the top right part of the message.
524e89e: fix AIOOBE
ee029e5: EA-33362 - assert: DocumentImpl.createRangeMarker
e2b452b: Merge remote-tracking branch 'origin/master'
551e0c5: fixed PY-12228 Project Interpreter: not possible to remove default-located interpreter from the list
df34787: IDEA-121533 INRE at com.intellij.util.indexing.FileBasedIndexImpl.a
a45e0df: EA-41231 (diagnostic)
1e94edc: Shadows improvement
cc01459: WEB-11194 runnerw.exe not working on win XP
10543d4: EA-54083, EA-54446 (premature disposal of default project prevented)
f455420: Merge remote-tracking branch 'origin/master'
0878209: Merging more than one newline in multi-line strings (PY-5532).
e3a7ad9: Implement 'Select all occurrences' action
3b82bfe: fixed PY-12211 Virtualenv interpreters associated with the current project are unsorted
e700d39: Merge remote-tracking branch 'origin/master'
7683348: updated after review.
25d38b4: fixed - toggle method breakpoint action added new breakpoint
d11a471: EA-52809 - IAE: GrClosureType.<init>
e8a5a73: EA-53171 Extracted a separate class for caching type definition stuff. Used CachedValueManager for caching class members, caches depends on its type definition changes and out_of_code_block_modification due to many synthetic members of a class get invalidated independently from its class.
287c82f: Removed TypeEvalContext parameter from PyType.isBuiltin()
466cbf4: EA-54177 - assert: Alarm._addRequest
168a1bc: show paths for detected sdk
eb3695f: new inference: non wildcard parametrization: reject primitive bounds
ab2348a: new inference: diamond in lambda return workaround
7fa42a6: java 1.8, stream api migration: temp disable for generics methods
6087cba: java 1.8, stream api migration: convert to method refs
fb65345: java 1.8, stream api migration: shorten class names
4e6b18e: switch on inplace scene builder
bae5e2a: IDEA-110943 apply patch: Do not add "-" at the end of new file - Part2
2544895: IDEA-121502 Breakpoint condition language is reverted to default once breakpoint properties opened
d96e7b4: do resolve symlinks in suggested python sdks
a52288b: IDEA-110943 apply patch: Do not add "-" at the end of new file
de93417: IDEA-121371 diff: change action caption
7805c3d: Merge remote-tracking branch 'origin/master'
e77d5bb: Switched to @NotNull call site in Callable.getCallType() and PyCallableType.getCallType()
9b235a9: updated after review.
eb0b14f: Changed Callable.getCallType() with explicit 'null' call site to Callable.getReturnType()
dd898e2: Introduced Callable.getCallType() instead of PyFunctionImpl.getReturnTypeWithoutCallSite()
112519d: Merge remote-tracking branch 'origin/master'
4f8a937: IDEA-73814 Scratchpad
257ba94: updated after review.
032ad71: Inlined getGenericReturnType()
888edb9: IDEA-121491 Breakpoints inside anonymous class used in a field initializer
9e9e8e5: Cache call site independent return types of callables in TypeEvalContext
513e07d: EA-54475
27ffe06: CR-IC-4596 (formatting)
f0d970f: use correct concurrency primitive
90c2460: notnull
4c29f54: javadoc
9b88e07: Merge remote-tracking branch 'origin/master'
a456069: diamonds are not available at this language level - testdata fixed
0cab1e2: java 1.8, stream api migration: collect (to be continued)
3f5e08e: do not throw exception
578ac0e: fix indents in testdata
3f111dc: EA-53845 fixed NPE. ProjectRootManager obviously cannot be obtained if delegate.getProject() == null. Some @NotNull & @Nullable added in relative places
2ff02a9: cleanup
f90ee78: Added Callable.getReturnType() and PyTypeProvider.getReturnType()
54786f4: Renamed PyTypeProvider.getReturnType() to getCallType()
ed026c0: Renamed Callable.getReturnType() to getCallType()
1f721bb: Added PyCallableType.getReturnType() for forthcoming return types caching
f65c546: myWatchedProjectCount should be nonnegative
3c66f51: introduced idea.no.system.path.space.monitoring property to skip checks for free space because it fails for yet unrecognized reasons (IDEA-118718)
2fb4a97: JavaFX Scene Builder integration
956b0e3: Exclude ui-designer-core from plugins
8339440: IDEA-121423 Groovy: don't add type arguments to text for reference generating since it can contain lexical errors. Add type arguments to generated reference instead.
fd724d2: IDEA-121082 Enter License dialog: cannot enter data if JetBrains Account fails or returns several licenses
1e5e753: IDEA-121359 License dialog: Undo not working in textfields
cb0399a: check for closure parameters: use method call conversion rules
914d6d4: Groovy: inference of closure parameter types: checks for explicitly declared types.
9446712: Duplicated error messages in @CompileStatic context fixed. Recoursive visitor is replaced with simple visitor, so we don't go inside child psi elements which can be inside @CompileStatic context
b7ba76c: Groovy: Support all ClosureSignatureHints
8951234: FromString hint: support correcr format. it describes a whole signature inside a single string.
22d33a0: ClosureSignatureHint works for closures with several parameters without declared types
d6f0faf: FromString hint: support options with a single String arg instead of an array of Strings
f30ccd9: Groovy: update mock groovy-2.3 build
258c222: Groovy: infrastructure for @ClosureParams support. FromString closure signature hint is supported
965c9b8: redundant code
17ad0ad: EA-53885 - CCE: GrIntroduceParameterProcessor.findUsages in-place introduce parameter is supported only for methods right now
d1b1b43: EA-54370 - IAE: GrIntroduceHandlerBase.getAnchor anchor should be @Nullable to get appropriate log message in case of null
d677a38: some null checks and cleanup
e5b4876: diff: DiffFragment.unchanged -> isEqual() == true
61b2c2a: diff: cleanup
b4a0790: Merge remote-tracking branch 'origin/master'
ac6700b: IDEA-121418 Update to EAP 134.1342 fails with access denied
41a88a4: diff: remove code duplication
45caaf6: diff: move HighlightingMode logic to TextCompareProcessor
ea4d527: EA-54427 - IAE: DiffUtil.getFramingColor
a30e0c6: Merge branch 'two-factor-auth'
49a7d1c: Merge branch 'diff-string'
eed23e9: diff: fix patience diff
442a1ad: Changes according to CR-IC-4570 (using VirtualFileWithId) and CR-IC-4490 (double checked locking)
01d1d11: A standalone EnforcedPlainTextFileTypeManagerTest
8207bd5: java: shorten references after refactoring
5cd9656: EA-54400 (getChildren() consistency guaranteed)
87f8b0f: search indexed files first, then elsewhere (not only whole-words, IDEA-121444)
d7e9631: search whole-words-only in indexed files first, then elsewhere (IDEA-121444)
9dab141: extract project scanning functionality to FindInProjectTask
7bc8adb: FindInProjectUtil cleanup & shortening
fbf5bbe: GeneralCommandLine: 'warn' level changed to 'info' level
7647e15: fix compilation under 1.8
e268b4d: EA-54442 - assert: ComponentManagerImpl.getComponent
c2bee64: restore error on diamonds under 1.6 (IDEA-121377)
0407c16: new inference: cleanup
d8b3e5c: new inference: captures should stay closed inside nested calls
e683dc8: new inference: wildcard parametrization for lambda with formal params: assignability check for complete parametrization only
cfcc34b: IDEA-121251 (stray annotation highlighted)
b8e291a: better tracing resource problem
32c5c60: correctly serialize multiline conditions and log messages
e78e195: do not save null in text and extra text
055191e: use chunk.getPresentableShortName in FormsInstrumenter
6a70bb8: regression: IDEA-121390 Breakpoints: mute on / off: breakpoint appearance updates only on focus change
f23249b: avoid type warning
0d528ac: use trove collections
3c4c139: IDEA-120290 Deprecated methods in import popup.
10ab0f9: don't enumerate all chunk members in compiler status messages
8e74f05: IDEA-121433 ('Auto-unboxing' inspection misses cases)
3a48f58: Merge remote-tracking branch 'origin/master'
1c9512a: Deployment based remote interpreters.
9cfc582: New plugin description
362d96b: New plugin description
a80e03c: New plugin description
7a68bd8: New plugin description
b3d6fcf: issue a clear compilation error when there's no groovy library
6fa1f58: IDEA-117325 Coloring of variable disappears when variable reassigned a value inside an if(){}
35040d4: IDEA-121253 Allow to edit/add contract annotation for library method at usage location
d5e833a: Merge remote-tracking branch 'origin/master'
a047666: new inference: non wildcard parametrization against the spec
ef581ff: restored method breakpoints notification
903d9cf: IDEA-121187 ("Method names differ only by case" is reported even if methods are different not only by case, but by signature as well)
59b0d0e: New plugin description
32e6a78: New plugin description
4da6bed: New plugin description
8f245e8: Merge branch 'python-fixes'
d99cf43: new "'ThreadLocalRandom' instance might be shared" inspection
728b702: improve description
b074b52: allow to set process handler
097ec87: Merge remote-tracking branch 'origin/master'
5ffd591: 'default charset for property files' option won't be ignored anymore
1234810: IDEA-120811 compile-server process hung with 0 CPU
a77644f: IDEA-117380 Can't remove multiple Maven projects at the same time
ff6b7d9: IDEA-121389 Breakpoint tooltip: duplicated information and red color
87346e3: Merge remote-tracking branch 'origin/master'
f26a54a: there is no template stuff in python community
e5552d8: fixed pycharm community detection
69cc1ef: remove GppCompilerTest
833bcfd: initialize LineSet before document changes
0ca5300: more tracing for myWatchedProjectsCount
99d35bf: IDEA-121393 Breakpoint: enabled breakpoint does not update its icon appearance
88b3931: License dialog: we don't need JBA availability check if actual license is JBA.
8fd9111: Fix for JToggleButton (we had no specific UI for Darcula/IntelliJ before)
f4ca614: Rename undo selection action
69b5912: Saving and loading of remote interpreters settings.
e7fd0b6: IDEA-121392 Breakpoint popup: click aside popup loses Suspend = Yes value
780a50b: IDEA-111432 Mnemonics changed for "Preserve case" and "Whole project"
a91ad4a: Don't require PsiFile.getText() for detecting Python charset declaration
3ca9628: remove ControlFlowUtils duplication
a1e2bb8: Remove unused ConditionalUtils
7b53c99: remove SideEffectChecker duplication
bcf9217: remove VariableAccessUtils duplication
a8412d2: plugin advertiser disabled for broken plugins (IDEA-121374)
2994241: Don't crawl down the tree for performance reasons, use cached globals
ba5925e: fixed ContextTest.testXDebugger test
0a6c9ae: test fixed
5690776: save memory on detected line separator
0b40c67: notnull
ed02fc9: optimisation
94f1638: javadoc
d37c7a9: EA-54432 - IAE: XDependentBreakpointManager.getMasterBreakpoint
df6f6f5: do not save empty condition and log message in breakpoints
a7c29b4: LanguageConsoleImpl calls createFile during initialization, so, inherited class cannot override it properly
cf066de: default methods: do not warn about protected methods from Object
5dd3ae6: Merge branch 'python-fixes'
229a0e9: CR-IC-4571 EditorExtensions.xml is overkill
018e061: WEB-4379 Smart step into does not give me all the methods
e79dc61: style
00e2508: IDEA-119238 Git and Hg Amend Commit: amend message updated for multi-root selection changes
e6d6bbb: Merge remote-tracking branch 'origin/master'
58d0444: IDEA-121383 Intellij EAP 1342 Does not start on Mac
39a393c: initialize default breakpoints for new project in tests
25e8977: prepare to fix WEB-4379 Smart step into does not give me all the methods, WEB-4440 Make debugger step inside the anonymous function of the $.each statement by default (or make it at least optional)
dda01ac: overrides, notnull
b6791ca: overrides
f1fef2c: correction to editor fixture to fix failing tests (IDEA-80056)
22985e2: load document LineSet lazily
13e43be: more debugging for GroovyCompilerTest
fdaed62: use IJ index-building classloader to speedup groovyc resolve when it's advantageous
80c7763: testdata fixed
e7cb908: new inference: method refs: apply reference rules first
cf7dff4: Support segue's
22a0e5f: compilation fix
e2c60e5: compilation fix
66a8ded: new inference: method refs: accept qualifier substitutor when nothing more could be inferred
e0f2061: select in project view: preserve registration order to prevent select in Packages by default
b31b23c: new inference: temp solution to exclude inference results from nested call of the same method on the outer level
5dd7e06: new inference: support for nested same method calls
fa6672f: new inference: simplify target type calculation
cbe62cc: new inference: guard fixed
a0f4efc: cleanup after batch folding operation end even in case of exception: to avoid observing invalid fold regions on subsequent batch folding operations
d63786d: allow non java xbreakpoints to be used in debugger-impl
600736c: preserve non java breakpoints in the BreakpointManager
bb586ed: java-xbreakpoints: do not save empty log message
bce82af: java-xbreakpoints: do not save empty conditions
1e9b8fb: java-xbreakpoints: rewrote breakpoints defaults
8541a5c: removed useless string conversion
2991835: java-xbreakpoints: support suspend policy defaults
d3a084dd: java-xbreakpoints: language selection support in condition and log expression
c7b3ad3: renamed attributes for exception breakpoint
b4df1c9: IDEA-121126 Debugger: mute breakpoints: Throwable at ApplicationImpl.assertReadAccessAllowed()
c388cfa: more clear breakpoint serialization format
3391b3b: fixed field and method breakpoints display name
d4f39df: java move to xbreakpoints: - cleanup after review
59b01e4: java move to xbreakpoints: - fixed old any exception breakpoint load
ca6bcc4: java move to xbreakpoints: - fixed breakpoint groupping
525d80d: java move to xbreakpoints 4: - fixed old breakpoints class deserialization
b903d10: java move to xbreakpoints 3: - breakpoint properties serialization fixes - import old java breakpoint - leave a copy for backward compatibility
d492412: java move to xbreakpoints 2: - cleanup - fixed tests - support run to cursor and smart step into - support add field/method breakpoint actions
7a3a6cf: java move to xbreakpoints: - removed java own breakpoints UI - added UI for java filters - added support for all kinds of java breakpoints
88189cc: New plugin description
17c097a: SlimEnterHandler should pass processing
f8d1847: New plugin description
2af38ae: new "Lambda parameter hides field" inspection
1f37c79: fix "Extract parameter as local variable" quickfix for expression lambda's
5fa2222: optimization for inspections tree filtering
a3bbf91: IDEA-105837 Intellij Idea caches maven snapshot dependencies forever
399fdef: fix multi-caret completion issues, make TypedHandlers supporting block selection work also with multiple carets (IDEA-80056)
a3258e2: IDEA-121283 Multiple Carets: Alt-J keyboard shortcut should be changed for Mac
13c7ba0: improve stub-psi-mismatch diagnostic: add language
140bfa4: test from jps modules extracted to separate modules to get rid of cyclic dependencies involving JPS modules
c367db2: 'Select in -> Project Structure' should select corresponding module when invoked on iml file
75feb75: EA-54419 (severity lowered)
93287e7: fixed PY-12248 Project Interpreters: redundant add virtualenv dialog on creating venv from project creation dialog
279985e: Faster isInBuilitins check that doesn't require resolve for non-builtin names
62df9b7: removed generate skeletons action
0cfaba5: New plugin description
2a39a63: IDEA-121285 Maven: missing classifier in managed dependency
16748dc: lazy icons for groovy elements
53ae56b: correct server log location in GroovyCompilerTest
13bfcb5: why does GroovyCompilerTest blink on TC?
5c2b079: IDEA-81276 Show the current program execution point does not bring hidden windows to front
9df88a0: overrides, notnull
4ecfba9: Merge remote-tracking branch 'origin/master'
eb1027b: fixed PY-12251 Project Interpreters: Create virtualenv from settings doesn't update warnigns about python package management tools
08190b2: IDEA-116029 in-place introduce variable name suggestions popup disappears before I can select anything
abf9500: Switched to potentially faster PyBuiltinCache.isInBuilins
7eebbf4: Fix for IDEA-121307 Cannot create new file (StubVirtualFile throws an exception on isDirectory)
daada4c: fixed PY-12257 IOOBE: CreateVirtualEnvDialog.setupDialog
2533839: do not duplicate existing sdks in create virtualenv
b649cb8b: Deprecated PyUtil.getConcealingParent
f16a6dd: Cleanup
ad552ed: CR-IC-4539
64d19ef: Moved isInBuiltins check for expressions to PyBuiltinCache
7113820: Github: do not provide Login/Password AuthData to Git on TwoFactor enabled
9194fc6: Renamed PyBuiltinCache.hasInBuiltins to isBuiltin
a4fef1b: LazyRangeMarkerFactory as project service — reapplied, add missed to RichPlatformPlugin.xml
82a44a6: Github: inspection warnings
92e93ca: Github: AtomicRef -> Ref
6a683af: Github: codereview
16d681e: Github: rewrite AuthDataHolder
741c46d: Github: do not rethrow exception twice
a33d7ef: Github: enable twofactor authorization
1f9c6da: EA-51130 (use data class' loader to register data flavor)
6f684e8: IDEA-121338 Multiple Carets: Menu items for multiple cursors are empty
50ad473: Revert: LazyRangeMarkerFactory as project service (b51fb7bf126a8c95ebf2223fb51c4b1d3faaa558)
e2b1588: ability to create OpenFileDescriptor using RangeMarker +review
d0ade84: LineColumnLazyMarker must compute delegate on start/end offset request +review
b51fb7b: LazyRangeMarkerFactory as project service +review
7cb4315: cleanup
104549e: update action presentations even if there are no mouse or key events
14e2cd6: fixed PY-12259 Assertion error on collecting Python installations on Mac
487e7c3: fixed PY-12261 Memory leak detected in python sdk details dialog
7e47f0e: UsefulTestCase.assertExists/assertDoesntExist for io.File
52ec148: platform: mute system notifications in tests and headless mode
5d41414: Switched from ArrayList to array for annotators for performance reasons
3174f1f: Merge remote-tracking branch 'origin/master'
340bdef: reverted nack template language selection to template language configurable (we don't have any template stuff in community edition)
ec14400: optimized icons
c741b28: Merge remote-tracking branch 'origin/master'
da79a3f: fixed PY-12267 Project Interpreters: inconsistent path separators for virtualenvs and base interpreters
abc49c3: added application root to the SDK search path on window (Education Edition attempt)
e1f5eb1: diff: do not create LineSeparator string every time
a7478db: diff: fix typo
41eed85: diff: rewrite DiffFragment
61dd3cd: diff: unify LineTokenizers
5ca37a6: diff: DiffString
c99c548: diff: fix patience diff
3717b9a: PY-12178 Support pull up / push down for properties (not ready yet: only properties excluded from other managers)
ad37f51: Merge remote-tracking branch 'origin/master'
eac76aa: fixed PY-12270 Project Interpreters: interpreter gets duplicated when hitting apply in multi-project settings window
094ac61: Merge remote-tracking branch 'origin/master'
5d4d015: Merge branch 'PY-10179' of https://github.com/Amarchuk/intellij-community into Amarchuk-PY-10179
be55f15: Merge remote-tracking branch 'origin/master'
68cfa2b: UI to create remote interpreter based on Vagrant.
150483d: fixed PY-12271 Project Interpreter: not able to set interpreter from Project Interpreters dialog when there are duplicated items in the list
40dd069: fixed PY-12272 Project Interpreter Setting Page: invalid alignment for multiproject list and packages table
3d19968: fix multi-line string with single quotes problem PY-12223
bf7f424: fix problem with single quote in project path http://youtrack.jetbrains.com/issue/PY-10179
Change-Id: I85e3d2231109799aab216989c887e0e48c87badb
Diffstat (limited to 'java')
237 files changed, 5905 insertions, 3974 deletions
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/StateCache.java b/java/compiler/impl/src/com/intellij/compiler/impl/StateCache.java index bd56b6653b91..631988e17577 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/StateCache.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/StateCache.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.PersistentHashMap; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import java.io.DataInput; import java.io.DataOutput; @@ -92,11 +93,11 @@ public abstract class StateCache<T> { private PersistentHashMap<String, T> createMap(final File file) throws IOException { return new PersistentHashMap<String,T>(file, new EnumeratorStringDescriptor(), new DataExternalizer<T>() { - public void save(final DataOutput out, final T value) throws IOException { + public void save(@NotNull final DataOutput out, final T value) throws IOException { StateCache.this.write(value, out); } - public T read(final DataInput in) throws IOException { + public T read(@NotNull final DataInput in) throws IOException { return StateCache.this.read(in); } }); diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java index a20c6975baa8..411fa24b2978 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java @@ -80,7 +80,7 @@ import java.util.concurrent.atomic.AtomicInteger; */ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.TranslatingCompilerFilesMonitor"); - private static final boolean ourDebugMode = false; + public static boolean ourDebugMode = false; private static final FileAttribute ourSourceFileAttribute = new FileAttribute("_make_source_file_info_", 3); private static final FileAttribute ourOutputFileAttribute = new FileAttribute("_make_output_file_info_", 3); @@ -89,7 +89,6 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { private final Object myDataLock = new Object(); private final TIntHashSet mySuspendedProjects = new TIntHashSet(); // projectId for all projects that should not be monitored - private volatile int myWatchedProjectsCount; private final TIntObjectHashMap<TIntHashSet> mySourcesToRecompile = new TIntObjectHashMap<TIntHashSet>(); // ProjectId->set of source file paths private PersistentHashMap<Integer, TIntObjectHashMap<Pair<Integer, Integer>>> myOutputRootsStorage; // ProjectId->map[moduleId->Pair(outputDirId, testOutputDirId)] @@ -196,7 +195,6 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { return; } FileUtil.createIfDoesntExist(CompilerPaths.getRebuildMarkerFile(project)); - --myWatchedProjectsCount; // cleanup internal structures to free memory mySourcesToRecompile.remove(projectId); myOutputsToDelete.remove(projectId); @@ -217,8 +215,8 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { public void watchProject(Project project) { synchronized (myDataLock) { - mySuspendedProjects.remove(getProjectId(project)); - ++myWatchedProjectsCount; + int projectId = getProjectId(project); + mySuspendedProjects.remove(projectId); } } @@ -600,7 +598,7 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { private void initOutputRootsFile(File rootsFile) throws IOException { myOutputRootsStorage = new PersistentHashMap<Integer, TIntObjectHashMap<Pair<Integer, Integer>>>(rootsFile, EnumeratorIntegerDescriptor.INSTANCE, new DataExternalizer<TIntObjectHashMap<Pair<Integer, Integer>>>() { - public void save(DataOutput out, TIntObjectHashMap<Pair<Integer, Integer>> value) throws IOException { + public void save(@NotNull DataOutput out, TIntObjectHashMap<Pair<Integer, Integer>> value) throws IOException { for (final TIntObjectIterator<Pair<Integer, Integer>> it = value.iterator(); it.hasNext();) { it.advance(); DataInputOutputUtil.writeINT(out, it.key()); @@ -610,7 +608,7 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { } } - public TIntObjectHashMap<Pair<Integer, Integer>> read(DataInput in) throws IOException { + public TIntObjectHashMap<Pair<Integer, Integer>> read(@NotNull DataInput in) throws IOException { final DataInputStream _in = (DataInputStream)in; final TIntObjectHashMap<Pair<Integer, Integer>> map = new TIntObjectHashMap<Pair<Integer, Integer>>(); while (_in.available() > 0) { @@ -1476,7 +1474,6 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { } public void beforeFileDeletion(@NotNull final VirtualFileEvent event) { - if (myWatchedProjectsCount == 0) return; final VirtualFile eventFile = event.getFile(); if ((LOG.isDebugEnabled() && eventFile.isDirectory()) || ourDebugMode) { final String message = "Processing file deletion: " + eventFile.getPresentableUrl(); @@ -1616,7 +1613,6 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { } private void processNewFile(final VirtualFile file, final boolean notifyServer) { - if (myWatchedProjectsCount == 0) return; final Ref<Boolean> isInContent = Ref.create(false); ApplicationManager.getApplication().runReadAction(new Runnable() { // need read action to ensure that the project was not disposed during the iteration over the project list diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/generic/GenericCompilerCache.java b/java/compiler/impl/src/com/intellij/compiler/impl/generic/GenericCompilerCache.java index 5741b9cf7949..4db878623df7 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/generic/GenericCompilerCache.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/generic/GenericCompilerCache.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -112,8 +112,8 @@ public class GenericCompilerCache<Key, SourceState, OutputState> { } public static class PersistentStateData<SourceState, OutputState> { - public final SourceState mySourceState; - public final OutputState myOutputState; + @NotNull public final SourceState mySourceState; + @NotNull public final OutputState myOutputState; private PersistentStateData(@NotNull SourceState sourceState, @NotNull OutputState outputState) { mySourceState = sourceState; @@ -139,14 +139,14 @@ public class GenericCompilerCache<Key, SourceState, OutputState> { } @Override - public void save(DataOutput out, KeyAndTargetData<Key> value) throws IOException { + public void save(@NotNull DataOutput out, KeyAndTargetData<Key> value) throws IOException { out.writeInt(value.myTarget); myKeyDescriptor.save(out, value.myKey); } @Override - public KeyAndTargetData<Key> read(DataInput in) throws IOException { + public KeyAndTargetData<Key> read(@NotNull DataInput in) throws IOException { int target = in.readInt(); final Key item = myKeyDescriptor.read(in); return getKeyAndTargetData(item, target); @@ -163,13 +163,13 @@ public class GenericCompilerCache<Key, SourceState, OutputState> { } @Override - public void save(DataOutput out, PersistentStateData<SourceState, OutputState> value) throws IOException { + public void save(@NotNull DataOutput out, PersistentStateData<SourceState, OutputState> value) throws IOException { mySourceStateExternalizer.save(out, value.mySourceState); myOutputStateExternalizer.save(out, value.myOutputState); } @Override - public PersistentStateData<SourceState, OutputState> read(DataInput in) throws IOException { + public PersistentStateData<SourceState, OutputState> read(@NotNull DataInput in) throws IOException { SourceState sourceState = mySourceStateExternalizer.read(in); OutputState outputState = myOutputStateExternalizer.read(in); return new PersistentStateData<SourceState,OutputState>(sourceState, outputState); diff --git a/java/compiler/impl/src/com/intellij/compiler/make/BackwardDependenciesStorage.java b/java/compiler/impl/src/com/intellij/compiler/make/BackwardDependenciesStorage.java index fb7a5c6eb280..006debb3b43a 100644 --- a/java/compiler/impl/src/com/intellij/compiler/make/BackwardDependenciesStorage.java +++ b/java/compiler/impl/src/com/intellij/compiler/make/BackwardDependenciesStorage.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -357,7 +357,7 @@ public class BackwardDependenciesStorage implements Flushable, Disposable { } private static class MyDataExternalizer implements DataExternalizer<DependenciesSet> { - public void save(DataOutput out, DependenciesSet ds) throws IOException { + public void save(@NotNull DataOutput out, DependenciesSet ds) throws IOException { final TIntHashSet classes = new TIntHashSet(); final Map<Dependency.FieldRef, TIntHashSet> fieldsMap = new HashMap<Dependency.FieldRef, TIntHashSet>(); final Map<Dependency.MethodRef, TIntHashSet> methodsMap = new HashMap<Dependency.MethodRef, TIntHashSet>(); @@ -414,7 +414,7 @@ public class BackwardDependenciesStorage implements Flushable, Disposable { } } - public DependenciesSet read(DataInput in) throws IOException { + public DependenciesSet read(@NotNull DataInput in) throws IOException { final Set<ReferencerItem> set = new THashSet<ReferencerItem>(); int classesCount = in.readInt(); diff --git a/java/compiler/impl/src/com/intellij/compiler/make/Cache.java b/java/compiler/impl/src/com/intellij/compiler/make/Cache.java index 2e3d5543214b..f80cb8e5bcaa 100644 --- a/java/compiler/impl/src/com/intellij/compiler/make/Cache.java +++ b/java/compiler/impl/src/com/intellij/compiler/make/Cache.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.EnumeratorIntegerDescriptor; import com.intellij.util.io.PersistentHashMap; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.DataInput; @@ -54,10 +55,10 @@ public class Cache { myStorePath = storePath; new File(storePath).mkdirs(); myQNameToClassInfoMap = new CachedPersistentHashMap<Integer, ClassInfo>(getOrCreateFile("classes"), EnumeratorIntegerDescriptor.INSTANCE, new DataExternalizer<ClassInfo>() { - public void save(DataOutput out, ClassInfo value) throws IOException { + public void save(@NotNull DataOutput out, ClassInfo value) throws IOException { value.save(out); } - public ClassInfo read(DataInput in) throws IOException { + public ClassInfo read(@NotNull DataInput in) throws IOException { return new ClassInfo(in); } }, cacheSize * 2) { @@ -71,11 +72,11 @@ public class Cache { myQNameToSubclassesMap = new CompilerDependencyStorage<Integer>(getOrCreateFile("subclasses"), EnumeratorIntegerDescriptor.INSTANCE, cacheSize); myRemoteQNames = new PersistentHashMap<Integer, Boolean>(getOrCreateFile("remote"), EnumeratorIntegerDescriptor.INSTANCE, new DataExternalizer<Boolean>() { - public void save(DataOutput out, Boolean value) throws IOException { + public void save(@NotNull DataOutput out, Boolean value) throws IOException { out.writeBoolean(value.booleanValue()); } - public Boolean read(DataInput in) throws IOException { + public Boolean read(@NotNull DataInput in) throws IOException { return in.readBoolean(); } }, cacheSize); diff --git a/java/compiler/impl/src/com/intellij/compiler/make/CompilerDependencyStorage.java b/java/compiler/impl/src/com/intellij/compiler/make/CompilerDependencyStorage.java index ea93f2193297..2466881b14fd 100644 --- a/java/compiler/impl/src/com/intellij/compiler/make/CompilerDependencyStorage.java +++ b/java/compiler/impl/src/com/intellij/compiler/make/CompilerDependencyStorage.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,14 +40,14 @@ public class CompilerDependencyStorage<Key> implements Flushable, Disposable { public CompilerDependencyStorage(File file, KeyDescriptor<Key> keyDescriptor, final int cacheSize) throws IOException { myMap = new PersistentHashMap<Key, int[]>(file, keyDescriptor, new DataExternalizer<int[]>() { - public void save(DataOutput out, int[] array) throws IOException { + public void save(@NotNull DataOutput out, int[] array) throws IOException { out.writeInt(array.length); for (int value : array) { out.writeInt(value); } } - public int[] read(DataInput in) throws IOException { + public int[] read(@NotNull DataInput in) throws IOException { final TIntHashSet set = new TIntHashSet(); DataInputStream stream = (DataInputStream)in; while(stream.available() > 0) { 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 13d9be0b5623..506580c351a4 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -928,6 +928,7 @@ public class BuildManager implements ApplicationComponent{ launcherCp.add(ClasspathBootstrap.getResourcePath(launcherClass)); launcherCp.add(compilerPath); ClasspathBootstrap.appendJavaCompilerClasspath(launcherCp); + launcherCp.addAll(BuildProcessClasspathManager.getLauncherClasspath(project)); cmdLine.addParameter("-classpath"); cmdLine.addParameter(classpathToString(launcherCp)); diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildProcessParametersProvider.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildProcessParametersProvider.java index 434633f3da47..1da1b5c26631 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildProcessParametersProvider.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildProcessParametersProvider.java @@ -27,10 +27,23 @@ import java.util.List; public abstract class BuildProcessParametersProvider { public static final ExtensionPointName<BuildProcessParametersProvider> EP_NAME = ExtensionPointName.create("com.intellij.buildProcess.parametersProvider"); + /** + * Override this method to include additional jars to the build process classpath + * @return list of paths to additional jars to be included to the build process classpath + */ public @NotNull List<String> getClassPath() { return Collections.emptyList(); } - + + /** + * Override this method to include additional jars to the build process launcher classpath. This may be needed if the plugin provides + * custom implementation of Java compiler which must be loaded by the same classloader as tools.jar + * @return list of paths to additional jars to be included to the build process launcher classpath + */ + public @NotNull List<String> getLauncherClassPath() { + return Collections.emptyList(); + } + public @NotNull List<String> getVMArguments() { return Collections.emptyList(); } diff --git a/java/compiler/impl/src/com/intellij/compiler/server/impl/BuildProcessClasspathManager.java b/java/compiler/impl/src/com/intellij/compiler/server/impl/BuildProcessClasspathManager.java index 2c06c2fb9eeb..5cef06dbab94 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/impl/BuildProcessClasspathManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/impl/BuildProcessClasspathManager.java @@ -141,4 +141,12 @@ public class BuildProcessClasspathManager { } return classpath; } + + public static List<String> getLauncherClasspath(Project project) { + final List<String> classpath = ContainerUtil.newArrayList(); + for (BuildProcessParametersProvider provider : project.getExtensions(BuildProcessParametersProvider.EP_NAME)) { + classpath.addAll(provider.getLauncherClassPath()); + } + return classpath; + } } diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/DummyPersistentState.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/DummyPersistentState.java index b3d66ce575fb..495b5a08758f 100644 --- a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/DummyPersistentState.java +++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/DummyPersistentState.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package com.intellij.openapi.compiler.generic; import com.intellij.util.io.DataExternalizer; +import org.jetbrains.annotations.NotNull; import java.io.DataInput; import java.io.DataOutput; @@ -33,11 +34,11 @@ public class DummyPersistentState { private static class DummyPersistentStateExternalizer implements DataExternalizer<DummyPersistentState> { @Override - public void save(DataOutput out, DummyPersistentState value) throws IOException { + public void save(@NotNull DataOutput out, DummyPersistentState value) throws IOException { } @Override - public DummyPersistentState read(DataInput in) throws IOException { + public DummyPersistentState read(@NotNull DataInput in) throws IOException { return INSTANCE; } } diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFilePersistentState.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFilePersistentState.java index e9ea9700af42..17739b154aa6 100644 --- a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFilePersistentState.java +++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFilePersistentState.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package com.intellij.openapi.compiler.generic; import com.intellij.util.io.DataExternalizer; +import org.jetbrains.annotations.NotNull; import java.io.DataInput; import java.io.DataOutput; @@ -38,12 +39,12 @@ public class VirtualFilePersistentState { private static class VirtualFileStateExternalizer implements DataExternalizer<VirtualFilePersistentState> { @Override - public void save(DataOutput out, VirtualFilePersistentState value) throws IOException { + public void save(@NotNull DataOutput out, VirtualFilePersistentState value) throws IOException { out.writeLong(value.getSourceTimestamp()); } @Override - public VirtualFilePersistentState read(DataInput in) throws IOException { + public VirtualFilePersistentState read(@NotNull DataInput in) throws IOException { return new VirtualFilePersistentState(in.readLong()); } diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileSetState.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileSetState.java index a22e80dd77de..cf74b55f6691 100644 --- a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileSetState.java +++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileSetState.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,7 +67,7 @@ public class VirtualFileSetState { private byte[] myBuffer = IOUtil.allocReadWriteUTFBuffer(); @Override - public void save(DataOutput out, VirtualFileSetState value) throws IOException { + public void save(@NotNull DataOutput out, VirtualFileSetState value) throws IOException { final Map<String, Long> dependencies = value.myTimestamps; out.writeInt(dependencies.size()); for (Map.Entry<String, Long> entry : dependencies.entrySet()) { @@ -77,7 +77,7 @@ public class VirtualFileSetState { } @Override - public VirtualFileSetState read(DataInput in) throws IOException { + public VirtualFileSetState read(@NotNull DataInput in) throws IOException { final VirtualFileSetState state = new VirtualFileSetState(); int size = in.readInt(); while (size-- > 0) { diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileWithDependenciesState.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileWithDependenciesState.java index 9f4a815304de..1b9aee4254a7 100644 --- a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileWithDependenciesState.java +++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileWithDependenciesState.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,7 +63,7 @@ public class VirtualFileWithDependenciesState { private byte[] myBuffer = IOUtil.allocReadWriteUTFBuffer(); @Override - public void save(DataOutput out, VirtualFileWithDependenciesState value) throws IOException { + public void save(@NotNull DataOutput out, VirtualFileWithDependenciesState value) throws IOException { out.writeLong(value.mySourceTimestamp); final Map<String, Long> dependencies = value.myDependencies; out.writeInt(dependencies.size()); @@ -74,7 +74,7 @@ public class VirtualFileWithDependenciesState { } @Override - public VirtualFileWithDependenciesState read(DataInput in) throws IOException { + public VirtualFileWithDependenciesState read(@NotNull DataInput in) throws IOException { final VirtualFileWithDependenciesState state = new VirtualFileWithDependenciesState(in.readLong()); int size = in.readInt(); while (size-- > 0) { diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactPackagingItemExternalizer.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactPackagingItemExternalizer.java index 030e9484ba26..c0a547e817d1 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactPackagingItemExternalizer.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactPackagingItemExternalizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.util.SmartList; import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.IOUtil; +import org.jetbrains.annotations.NotNull; import java.io.DataInput; import java.io.DataOutput; @@ -31,7 +32,7 @@ public class ArtifactPackagingItemExternalizer implements DataExternalizer<Artif private byte[] myBuffer = IOUtil.allocReadWriteUTFBuffer(); @Override - public void save(DataOutput out, ArtifactPackagingItemOutputState value) throws IOException { + public void save(@NotNull DataOutput out, ArtifactPackagingItemOutputState value) throws IOException { out.writeInt(value.myDestinations.size()); for (Pair<String, Long> pair : value.myDestinations) { IOUtil.writeUTFFast(myBuffer, out, pair.getFirst()); @@ -40,7 +41,7 @@ public class ArtifactPackagingItemExternalizer implements DataExternalizer<Artif } @Override - public ArtifactPackagingItemOutputState read(DataInput in) throws IOException { + public ArtifactPackagingItemOutputState read(@NotNull DataInput in) throws IOException { int size = in.readInt(); SmartList<Pair<String, Long>> destinations = new SmartList<Pair<String, Long>>(); while (size-- > 0) { diff --git a/java/debugger/impl/src/com/intellij/debugger/InstanceFilter.java b/java/debugger/impl/src/com/intellij/debugger/InstanceFilter.java index 9ce095c038dc..09be13076ca1 100644 --- a/java/debugger/impl/src/com/intellij/debugger/InstanceFilter.java +++ b/java/debugger/impl/src/com/intellij/debugger/InstanceFilter.java @@ -20,6 +20,9 @@ import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.JDOMExternalizable; import com.intellij.openapi.util.WriteExternalException; import com.intellij.ui.classFilter.ClassFilter; +import com.intellij.util.xmlb.annotations.Attribute; +import com.intellij.util.xmlb.annotations.Tag; +import com.intellij.util.xmlb.annotations.Transient; import org.jdom.Element; /** @@ -27,10 +30,13 @@ import org.jdom.Element; * Date: Aug 29, 2003 * Time: 2:49:27 PM */ +@Tag("instance-filter") public class InstanceFilter implements JDOMExternalizable{ public static final InstanceFilter[] EMPTY_ARRAY = new InstanceFilter[0]; - + + @Attribute("id") public long ID = 0; + @Attribute("enabled") public boolean ENABLED = true; public InstanceFilter() { @@ -41,10 +47,12 @@ public class InstanceFilter implements JDOMExternalizable{ this.ENABLED = ENABLED; } + @Transient public long getId() { return ID; } + @Transient public boolean isEnabled() { return ENABLED; } diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JavaEditBreakpointActionHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/JavaEditBreakpointActionHandler.java deleted file mode 100644 index 9ed769aee350..000000000000 --- a/java/debugger/impl/src/com/intellij/debugger/actions/JavaEditBreakpointActionHandler.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.debugger.actions; - -import com.intellij.debugger.DebuggerManagerEx; -import com.intellij.debugger.ui.breakpoints.BreakpointFactory; -import com.intellij.debugger.ui.breakpoints.BreakpointPropertiesPanel; -import com.intellij.debugger.ui.breakpoints.BreakpointWithHighlighter; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.markup.GutterIconRenderer; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.popup.Balloon; -import com.intellij.openapi.ui.popup.JBPopupListener; -import com.intellij.openapi.ui.popup.LightweightWindowEvent; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.wm.IdeFocusManager; -import com.intellij.util.ui.UIUtil; -import com.intellij.xdebugger.impl.actions.EditBreakpointActionHandler; -import com.intellij.xdebugger.impl.breakpoints.XBreakpointUtil; -import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointsDialogFactory; -import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; -import org.jetbrains.annotations.NotNull; - -import javax.swing.*; -import java.awt.*; - -public class JavaEditBreakpointActionHandler extends EditBreakpointActionHandler { - @Override - protected void doShowPopup(final Project project, final JComponent component, final Point whereToShow, final Object breakpoint) { - if (!(breakpoint instanceof BreakpointWithHighlighter)) { - return; - } - - final BreakpointWithHighlighter javaBreakpoint = (BreakpointWithHighlighter)breakpoint; - BreakpointFactory breakpointFactory = null; - for (BreakpointFactory factory : BreakpointFactory.EXTENSION_POINT_NAME.getExtensions()) { - if (factory.getBreakpointCategory().equals(javaBreakpoint.getCategory())) { - breakpointFactory = factory; - } - } - assert breakpointFactory != null : "can't find factory for breakpoint " + javaBreakpoint; - - final BreakpointPropertiesPanel propertiesPanel = breakpointFactory.createBreakpointPropertiesPanel(project, true); - assert propertiesPanel != null; - propertiesPanel.initFrom(javaBreakpoint, false); - - final JComponent mainPanel = propertiesPanel.getPanel(); - final JBPopupListener saveOnClose = new JBPopupListener.Adapter() { - @Override - public void onClosed(LightweightWindowEvent event) { - propertiesPanel.saveTo(javaBreakpoint); - propertiesPanel.dispose(); - DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().fireBreakpointChanged(javaBreakpoint); - } - }; - - final Runnable showMoreOptions = new Runnable() { - @Override - public void run() { - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - BreakpointsDialogFactory.getInstance(project).showDialog(javaBreakpoint); - } - }); - } - }; - - final Balloon balloon = DebuggerUIUtil.showBreakpointEditor(project, mainPanel, whereToShow, component, showMoreOptions, breakpoint); - balloon.addListener(saveOnClose); - - propertiesPanel.setDelegate(new BreakpointPropertiesPanel.Delegate() { - @Override - public void showActionsPanel() { - propertiesPanel.setActionsPanelVisible(true); - balloon.hide(); - DebuggerUIUtil.showBreakpointEditor(project, mainPanel, whereToShow, component, showMoreOptions, breakpoint).addListener(saveOnClose); - } - }); - - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - IdeFocusManager.findInstance().requestFocus(mainPanel, true); - } - }); - } - - @Override - public boolean isEnabled(@NotNull Project project, AnActionEvent event) { - DataContext dataContext = event.getDataContext(); - Editor editor = CommonDataKeys.EDITOR.getData(dataContext); - if (editor == null) { - return false; - } - final Pair<GutterIconRenderer,Object> pair = XBreakpointUtil.findSelectedBreakpoint(project, editor); - return pair.first != null && pair.second instanceof BreakpointWithHighlighter; - } -} diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JumpToObjectAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/JumpToObjectAction.java index 89e32bc28683..498ee6d44417 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/JumpToObjectAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/JumpToObjectAction.java @@ -35,6 +35,7 @@ import java.util.List; public class JumpToObjectAction extends DebuggerAction{ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.actions.JumpToObjectAction"); + @Override public void actionPerformed(AnActionEvent e) { DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); if(selectedNode == null) { @@ -55,6 +56,7 @@ public class JumpToObjectAction extends DebuggerAction{ debugProcess.getManagerThread().schedule(new NavigateCommand(debuggerContext, (ValueDescriptor)descriptor, debugProcess, e)); } + @Override public void update(final AnActionEvent e) { if(!isFirstStart(e)) { return; @@ -82,7 +84,7 @@ public class JumpToObjectAction extends DebuggerAction{ } } - private SourcePosition calcPosition(final ValueDescriptor descriptor, final DebugProcessImpl debugProcess) throws ClassNotLoadedException { + private static SourcePosition calcPosition(final ValueDescriptor descriptor, final DebugProcessImpl debugProcess) throws ClassNotLoadedException { final Value value = descriptor.getValue(); if(value == null) { return null; @@ -103,10 +105,11 @@ public class JumpToObjectAction extends DebuggerAction{ if(locations.size() > 0) { final Location location = locations.get(0); return ApplicationManager.getApplication().runReadAction(new Computable<SourcePosition>() { + @Override public SourcePosition compute() { SourcePosition position = debugProcess.getPositionManager().getSourcePosition(location); // adjust position for non-anonymous classes - if (clsType.name().indexOf("$") < 0) { + if (clsType.name().indexOf('$') < 0) { final PsiClass classAt = position != null? JVMNameUtil.getClassAt(position) : null; if (classAt != null) { final SourcePosition classPosition = SourcePosition.createFromElement(classAt); @@ -130,13 +133,15 @@ public class JumpToObjectAction extends DebuggerAction{ return null; } - private class NavigateCommand extends SourcePositionCommand { + private static class NavigateCommand extends SourcePositionCommand { public NavigateCommand(final DebuggerContextImpl debuggerContext, final ValueDescriptor descriptor, final DebugProcessImpl debugProcess, final AnActionEvent e) { super(debuggerContext, descriptor, debugProcess, e); } + @Override protected NavigateCommand createRetryCommand() { return new NavigateCommand(myDebuggerContext, myDescriptor, myDebugProcess, myActionEvent); } + @Override protected void doAction(final SourcePosition sourcePosition) { if (sourcePosition != null) { sourcePosition.navigate(true); @@ -144,19 +149,21 @@ public class JumpToObjectAction extends DebuggerAction{ } } - private class EnableCommand extends SourcePositionCommand { + private static class EnableCommand extends SourcePositionCommand { public EnableCommand(final DebuggerContextImpl debuggerContext, final ValueDescriptor descriptor, final DebugProcessImpl debugProcess, final AnActionEvent e) { super(debuggerContext, descriptor, debugProcess, e); } + @Override protected EnableCommand createRetryCommand() { return new EnableCommand(myDebuggerContext, myDescriptor, myDebugProcess, myActionEvent); } + @Override protected void doAction(final SourcePosition sourcePosition) { enableAction(myActionEvent, sourcePosition != null); } } - public abstract class SourcePositionCommand extends SuspendContextCommandImpl { + public abstract static class SourcePositionCommand extends SuspendContextCommandImpl { protected final DebuggerContextImpl myDebuggerContext; protected final ValueDescriptor myDescriptor; protected final DebugProcessImpl myDebugProcess; @@ -173,6 +180,7 @@ public class JumpToObjectAction extends DebuggerAction{ myActionEvent = actionEvent; } + @Override public final void contextAction() throws Exception { try { doAction(calcPosition(myDescriptor, myDebugProcess)); diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/QuickEvaluateActionHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/QuickEvaluateActionHandler.java index d67b2bf45572..6eedff4136ea 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/QuickEvaluateActionHandler.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/QuickEvaluateActionHandler.java @@ -21,34 +21,37 @@ package com.intellij.debugger.actions; import com.intellij.debugger.DebuggerManagerEx; -import com.intellij.debugger.settings.DebuggerSettings; import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.settings.DebuggerSettings; import com.intellij.debugger.ui.ValueHint; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler; import com.intellij.xdebugger.impl.evaluate.quick.common.AbstractValueHint; +import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler; import com.intellij.xdebugger.impl.evaluate.quick.common.ValueHintType; import org.jetbrains.annotations.NotNull; import java.awt.*; public class QuickEvaluateActionHandler extends QuickEvaluateHandler { - + @Override public boolean isEnabled(@NotNull final Project project) { DebuggerSession debuggerSession = DebuggerManagerEx.getInstanceEx(project).getContext().getDebuggerSession(); return debuggerSession != null && debuggerSession.isPaused(); } + @Override public AbstractValueHint createValueHint(@NotNull final Project project, @NotNull final Editor editor, @NotNull final Point point, final ValueHintType type) { return ValueHint.createValueHint(project, editor, point, type); } + @Override public boolean canShowHint(@NotNull final Project project) { DebuggerSession debuggerSession = DebuggerManagerEx.getInstanceEx(project).getContext().getDebuggerSession(); return debuggerSession != null && debuggerSession.isAttached(); } + @Override public int getValueLookupDelay(final Project project) { return DebuggerSettings.getInstance().VALUE_LOOKUP_DELAY; } diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java index fda3e6128a3e..693b7f4917a5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java @@ -22,7 +22,6 @@ import com.intellij.debugger.ui.breakpoints.BreakpointManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditorManager; @@ -41,7 +40,7 @@ public class ToggleBreakpointEnabledAction extends AnAction { Breakpoint breakpoint = findBreakpoint(project); if (breakpoint != null) { final BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager(); - breakpointManager.setBreakpointEnabled(breakpoint, !breakpoint.ENABLED); + breakpointManager.setBreakpointEnabled(breakpoint, !breakpoint.isEnabled()); } } 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 39a397755a5e..a7e00ee0dd72 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java @@ -81,7 +81,7 @@ public class ToggleFieldBreakpointAction extends AnAction { long id = object.uniqueID(); InstanceFilter[] instanceFilters = new InstanceFilter[] { InstanceFilter.create(Long.toString(id))}; fieldBreakpoint.setInstanceFilters(instanceFilters); - fieldBreakpoint.INSTANCE_FILTERS_ENABLED = true; + fieldBreakpoint.setInstanceFiltersEnabled(true); } } } diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleLineBreakpointActionHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleLineBreakpointActionHandler.java deleted file mode 100644 index 650e7c37cf70..000000000000 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleLineBreakpointActionHandler.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.debugger.actions; - -import com.intellij.codeInsight.folding.impl.actions.ExpandRegionAction; -import com.intellij.debugger.DebuggerManagerEx; -import com.intellij.debugger.engine.DebuggerUtils; -import com.intellij.debugger.engine.requests.RequestManagerImpl; -import com.intellij.debugger.ui.breakpoints.Breakpoint; -import com.intellij.debugger.ui.breakpoints.BreakpointManager; -import com.intellij.debugger.ui.breakpoints.LineBreakpoint; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.FoldRegion; -import com.intellij.openapi.fileEditor.FileDocumentManager; -import com.intellij.openapi.fileEditor.FileEditorManager; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.*; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.xdebugger.impl.actions.DebuggerActionHandler; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public class ToggleLineBreakpointActionHandler extends DebuggerActionHandler { - - private final boolean myTemporary; - - public ToggleLineBreakpointActionHandler(boolean temporary) { - - myTemporary = temporary; - } - - public boolean isEnabled(@NotNull final Project project, final AnActionEvent event) { - PlaceInDocument place = getPlace(project, event); - if (place != null) { - final Document document = place.getDocument(); - final int offset = place.getOffset(); - int line = document.getLineNumber(offset); - - VirtualFile file = FileDocumentManager.getInstance().getFile(document); - PsiFile psiFile = PsiManager.getInstance(project).findFile(file); - if (DebuggerUtils.supportsJVMDebugging(file.getFileType()) || DebuggerUtils.supportsJVMDebugging(psiFile)) { - final BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager(); - return breakpointManager.findBreakpoint(document, offset, LineBreakpoint.CATEGORY) != null || - LineBreakpoint.canAddLineBreakpoint(project, document, line); - } - } - - return false; - } - - public void perform(@NotNull final Project project, final AnActionEvent event) { - PlaceInDocument place = getPlace(project, event); - if(place == null) { - return; - } - - Editor editor = event.getData(CommonDataKeys.EDITOR); - ExpandRegionAction.expandRegionAtCaret(project, editor); - - Document document = place.getDocument(); - int line = document.getLineNumber(place.getOffset()); - if (editor != null && editor.getCaretModel().getVisualPosition().line != line) { - editor.getCaretModel().moveToOffset(place.getOffset()); - } - - DebuggerManagerEx debugManager = DebuggerManagerEx.getInstanceEx(project); - if (debugManager == null) { - return; - } - BreakpointManager manager = debugManager.getBreakpointManager(); - final Breakpoint breakpoint = manager.findBreakpoint(document, place.getOffset(), LineBreakpoint.CATEGORY); - if(breakpoint == null) { - LineBreakpoint lineBreakpoint = manager.addLineBreakpoint(document, line); - if(lineBreakpoint != null) { - lineBreakpoint.REMOVE_AFTER_HIT = myTemporary; - RequestManagerImpl.createRequests(lineBreakpoint); - } - } - else { - if (!breakpoint.REMOVE_AFTER_HIT && myTemporary) { - breakpoint.REMOVE_AFTER_HIT = true; - breakpoint.updateUI(); - } - else { - manager.removeBreakpoint(breakpoint); - } - } - } - - private static boolean containsOnlyDeclarations(int line, Document document, PsiFile file) { - int lineStart = document.getLineStartOffset(line); - int lineEnd = document.getLineEndOffset(line); - PsiElement start = file.findElementAt(lineStart); - PsiElement end = file.findElementAt(lineEnd - 1); - if (start == null || end == null) return false; - - PsiElement commonParent = PsiTreeUtil.findCommonParent(start, end); - for (PsiElement element : PsiTreeUtil.findChildrenOfAnyType(commonParent, PsiStatement.class, PsiExpression.class)) { - if (new TextRange(lineStart, lineEnd).contains(element.getTextRange().getStartOffset())) { - return false; - } - } - return true; - } - - @Nullable - private static PlaceInDocument getPlace(@NotNull final Project project, AnActionEvent event) { - Editor editor = event.getData(CommonDataKeys.EDITOR); - if(editor == null) { - editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); - } - if (editor == null) { - return null; - } - - final Document document = editor.getDocument(); - PsiDocumentManager.getInstance(project).commitDocument(document); - PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document); - if (file == null) { - return null; - } - - // if several lines are merged into one visual line (using folding), try to find the most appropriate of those lines - int visualLine = editor.getCaretModel().getVisualPosition().getLine(); - int visibleOffset = editor.getCaretModel().getOffset(); - while (editor.offsetToVisualPosition(visibleOffset).line == visualLine) { - int line = document.getLineNumber(visibleOffset); - if (!containsOnlyDeclarations(line, document, file)) { - return new PlaceInDocument(document, visibleOffset); - } - int lineEndOffset = document.getLineEndOffset(line); - FoldRegion region = editor.getFoldingModel().getCollapsedRegionAtOffset(lineEndOffset); - if (region != null) { - int foldEnd = region.getEndOffset(); - if (foldEnd > lineEndOffset) { - visibleOffset = foldEnd; - continue; - } - } - visibleOffset = lineEndOffset + 1; - } - - return new PlaceInDocument(document, editor.getCaretModel().getOffset()); - } -}
\ No newline at end of file diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java b/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java index 49d3cae977f0..399c55fd00e5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java @@ -17,22 +17,24 @@ package com.intellij.debugger.engine; import com.intellij.debugger.NoDataException; import com.intellij.debugger.PositionManager; +import com.intellij.debugger.PositionManagerEx; import com.intellij.debugger.SourcePosition; import com.intellij.debugger.requests.ClassPrepareRequestor; -import com.intellij.openapi.diagnostic.Logger; +import com.intellij.xdebugger.frame.XStackFrame; import com.sun.jdi.Location; import com.sun.jdi.ReferenceType; import com.sun.jdi.request.ClassPrepareRequest; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collections; import java.util.List; -public class CompoundPositionManager implements PositionManager{ - private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.CompoundPositionManager"); +public class CompoundPositionManager extends PositionManagerEx { private final ArrayList<PositionManager> myPositionManagers = new ArrayList<PositionManager>(); + @SuppressWarnings("UnusedDeclaration") public CompoundPositionManager() { } @@ -45,6 +47,7 @@ public class CompoundPositionManager implements PositionManager{ myPositionManagers.add(0, manager); } + @Override public SourcePosition getSourcePosition(Location location) { for (PositionManager positionManager : myPositionManagers) { try { @@ -56,6 +59,7 @@ public class CompoundPositionManager implements PositionManager{ return null; } + @Override @NotNull public List<ReferenceType> getAllClasses(SourcePosition classPosition) { for (PositionManager positionManager : myPositionManagers) { @@ -68,6 +72,7 @@ public class CompoundPositionManager implements PositionManager{ return Collections.emptyList(); } + @Override @NotNull public List<Location> locationsOfLine(ReferenceType type, SourcePosition position) { for (PositionManager positionManager : myPositionManagers) { @@ -80,6 +85,7 @@ public class CompoundPositionManager implements PositionManager{ return Collections.emptyList(); } + @Override public ClassPrepareRequest createPrepareRequest(ClassPrepareRequestor requestor, SourcePosition position) { for (PositionManager positionManager : myPositionManagers) { try { @@ -91,4 +97,18 @@ public class CompoundPositionManager implements PositionManager{ return null; } + + @Nullable + @Override + public XStackFrame createStackFrame(@NotNull Location location) { + for (PositionManager positionManager : myPositionManagers) { + if (positionManager instanceof PositionManagerEx) { + XStackFrame xStackFrame = ((PositionManagerEx)positionManager).createStackFrame(location); + if (xStackFrame != null) { + return xStackFrame; + } + } + } + return null; + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/ContextUtil.java b/java/debugger/impl/src/com/intellij/debugger/engine/ContextUtil.java index bfd7d050adc8..26903c87ca4f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/ContextUtil.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/ContextUtil.java @@ -53,8 +53,8 @@ public class ContextUtil { try { location = frameProxy.location(); } - catch (Throwable th) { - LOG.debug(th); + catch (Throwable e) { + LOG.debug(e); } final CompoundPositionManager positionManager = debugProcess.getPositionManager(); if (positionManager == null) { @@ -63,7 +63,8 @@ public class ContextUtil { } try { return positionManager.getSourcePosition(location); - } catch (IndexNotReadyException e) { + } + catch (IndexNotReadyException ignored) { return null; } } @@ -124,10 +125,10 @@ public class ContextUtil { } return codeBlockFromText; } - catch (IncorrectOperationException e) { + catch (IncorrectOperationException ignored) { return element; } - catch (EvaluateException e) { + catch (EvaluateException ignored) { return element; } finally { 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 a5b1be2ba733..b660d5f1ed6e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java @@ -57,9 +57,9 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.openapi.wm.ToolWindowId; import com.intellij.openapi.wm.WindowManager; import com.intellij.psi.PsiDocumentManager; @@ -77,6 +77,7 @@ import com.sun.jdi.connect.*; import com.sun.jdi.request.EventRequest; import com.sun.jdi.request.EventRequestManager; import com.sun.jdi.request.StepRequest; +import gnu.trove.THashMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -88,7 +89,7 @@ import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -public abstract class DebugProcessImpl implements DebugProcess { +public abstract class DebugProcessImpl extends UserDataHolderBase implements DebugProcess { private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.DebugProcessImpl"); @NonNls private static final String SOCKET_ATTACHING_CONNECTOR_NAME = "com.sun.jdi.SocketAttach"; @@ -111,26 +112,26 @@ public abstract class DebugProcessImpl implements DebugProcess { protected static final int STATE_DETACHED = 3; protected final AtomicInteger myState = new AtomicInteger(STATE_INITIAL); - private ExecutionResult myExecutionResult; + private ExecutionResult myExecutionResult; private RemoteConnection myConnection; private ConnectionServiceWrapper myConnectionService; private Map<String, Connector.Argument> myArguments; private final List<NodeRenderer> myRenderers = new ArrayList<NodeRenderer>(); - private final Map<Type, NodeRenderer> myNodeRederersMap = new com.intellij.util.containers.HashMap<Type, NodeRenderer>(); - private final NodeRendererSettingsListener mySettingsListener = new NodeRendererSettingsListener() { - public void renderersChanged() { - myNodeRederersMap.clear(); - myRenderers.clear(); - loadRenderers(); - } - }; + private final Map<Type, NodeRenderer> myNodeRenderersMap = new THashMap<Type, NodeRenderer>(); + private final NodeRendererSettingsListener mySettingsListener = new NodeRendererSettingsListener() { + @Override + public void renderersChanged() { + myNodeRenderersMap.clear(); + myRenderers.clear(); + loadRenderers(); + } + }; private final SuspendManagerImpl mySuspendManager = new SuspendManagerImpl(this); protected CompoundPositionManager myPositionManager = null; private volatile DebuggerManagerThreadImpl myDebuggerManagerThread; - private final HashMap myUserData = new HashMap(); private static final int LOCAL_START_TIMEOUT = 30000; private final Semaphore myWaitFor = new Semaphore(); @@ -141,9 +142,6 @@ public abstract class DebugProcessImpl implements DebugProcess { private final Disposable myDisposable = Disposer.newDisposable(); private final Alarm myStatusUpdateAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD, myDisposable); - /** @noinspection FieldCanBeLocal*/ - private volatile boolean myDebugProcessStarted = false; - protected DebugProcessImpl(Project project) { myProject = project; myRequestManager = new RequestManagerImpl(this); @@ -153,6 +151,7 @@ public abstract class DebugProcessImpl implements DebugProcess { private void loadRenderers() { getManagerThread().invoke(new DebuggerCommandImpl() { + @Override protected void action() throws Exception { try { final NodeRendererSettings rendererSettings = NodeRendererSettings.getInstance(); @@ -164,6 +163,7 @@ public abstract class DebugProcessImpl implements DebugProcess { } finally { DebuggerInvocationUtil.swingInvokeLater(myProject, new Runnable() { + @Override public void run() { final DebuggerSession session = mySession; if (session != null && session.isAttached()) { @@ -215,7 +215,7 @@ public abstract class DebugProcessImpl implements DebugProcess { return getDefaultRenderer(type); } - NodeRenderer renderer = myNodeRederersMap.get(type); + NodeRenderer renderer = myNodeRenderersMap.get(type); if(renderer == null) { for (final NodeRenderer nodeRenderer : myRenderers) { if (nodeRenderer.isApplicable(type)) { @@ -226,7 +226,7 @@ public abstract class DebugProcessImpl implements DebugProcess { if (renderer == null) { renderer = getDefaultRenderer(type); } - myNodeRederersMap.put(type, renderer); + myNodeRenderersMap.put(type, renderer); } return renderer; @@ -308,7 +308,7 @@ public abstract class DebugProcessImpl implements DebugProcess { private void stopConnecting() { DebuggerManagerThreadImpl.assertIsManagerThread(); - Map arguments = myArguments; + Map<String, Connector.Argument> arguments = myArguments; try { if (arguments == null) { return; @@ -423,7 +423,7 @@ public abstract class DebugProcessImpl implements DebugProcess { final List<StepRequest> toDelete = new ArrayList<StepRequest>(stepRequests.size()); for (final StepRequest request : stepRequests) { ThreadReference threadReference = request.thread(); - // [jeka] on attempt to delete a request assigned to a thread with unknown status, a JDWP error occures + // [jeka] on attempt to delete a request assigned to a thread with unknown status, a JDWP error occurs try { if (threadReference.status() != ThreadReference.THREAD_STATUS_UNKNOWN && (stepThread == null || stepThread.equals(threadReference))) { toDelete.add(request); @@ -444,7 +444,7 @@ public abstract class DebugProcessImpl implements DebugProcess { StackFrameProxyImpl stackFrame = thread.frame(0); if (stackFrame != null) { Location location = stackFrame.location(); - ReferenceType referenceType = location.declaringType(); + ReferenceType referenceType = location == null ? null : location.declaringType(); if (referenceType != null) { return referenceType.name(); } @@ -477,7 +477,7 @@ public abstract class DebugProcessImpl implements DebugProcess { if (address == null) { throw new CantRunException(DebuggerBundle.message("error.no.debug.listen.port")); } - // negative port number means the caller leaves to debugger to decide at which hport to listen + // negative port number means the caller leaves to debugger to decide at which port to listen //noinspection HardCodedStringLiteral final Connector.Argument portArg = myConnection.isUseSockets() ? myArguments.get("port") : myArguments.get("name"); if (portArg != null) { @@ -498,10 +498,10 @@ public abstract class DebugProcessImpl implements DebugProcess { try { connector.stopListening(myArguments); } - catch (IllegalArgumentException e) { + catch (IllegalArgumentException ignored) { // ignored } - catch (IllegalConnectorArgumentsException e) { + catch (IllegalConnectorArgumentsException ignored) { // ignored } } @@ -572,6 +572,7 @@ public abstract class DebugProcessImpl implements DebugProcess { if (!myStatusUpdateAlarm.isDisposed()) { myStatusUpdateAlarm.cancelAllRequests(); myStatusUpdateAlarm.addRequest(new Runnable() { + @Override public void run() { final WindowManager wm = WindowManager.getInstance(); if (wm != null) { @@ -614,6 +615,7 @@ public abstract class DebugProcessImpl implements DebugProcess { final String version = vm.version(); if ("1.4.0".equals(version)) { SwingUtilities.invokeLater(new Runnable() { + @Override public void run() { Messages.showMessageDialog( getProject(), @@ -633,10 +635,12 @@ public abstract class DebugProcessImpl implements DebugProcess { myEvaluationDispatcher.removeListener(evaluationListener); } + @Override public void addDebugProcessListener(DebugProcessListener listener) { myDebugProcessDispatcher.addListener(listener); } + @Override public void removeDebugProcessListener(DebugProcessListener listener) { myDebugProcessDispatcher.removeListener(listener); } @@ -668,18 +672,12 @@ public abstract class DebugProcessImpl implements DebugProcess { return myConnection; } + @Override public ExecutionResult getExecutionResult() { return myExecutionResult; } - public <T> T getUserData(Key<T> key) { - return (T)myUserData.get(key); - } - - public <T> void putUserData(Key<T> key, T value) { - myUserData.put(key, value); - } - + @Override public Project getProject() { return myProject; } @@ -698,22 +696,27 @@ public abstract class DebugProcessImpl implements DebugProcess { return myState.get() == STATE_INITIAL; } + @Override public boolean isAttached() { return myState.get() == STATE_ATTACHED; } + @Override public boolean isDetached() { return myState.get() == STATE_DETACHED; } + @Override public boolean isDetaching() { return myState.get() == STATE_DETACHING; } + @Override public RequestManagerImpl getRequestsManager() { return myRequestManager; } + @Override public VirtualMachineProxyImpl getVirtualMachineProxy() { DebuggerManagerThreadImpl.assertIsManagerThread(); final VirtualMachineProxyImpl vm = myVirtualMachineProxy; @@ -723,6 +726,7 @@ public abstract class DebugProcessImpl implements DebugProcess { return vm; } + @Override public void appendPositionManager(final PositionManager positionManager) { DebuggerManagerThreadImpl.assertIsManagerThread(); myPositionManager.appendPositionManager(positionManager); @@ -756,7 +760,7 @@ public abstract class DebugProcessImpl implements DebugProcess { myVirtualMachineProxy = null; myPositionManager = null; myReturnValueWatcher = null; - myNodeRederersMap.clear(); + myNodeRenderersMap.clear(); myRenderers.clear(); DebuggerUtils.cleanupAfterProcessFinish(this); myState.set(STATE_DETACHED); @@ -852,6 +856,7 @@ public abstract class DebugProcessImpl implements DebugProcess { Disposer.dispose(myDisposable); } + @Override public DebuggerManagerThreadImpl getManagerThread() { if (myDebuggerManagerThread == null) { synchronized (this) { @@ -868,11 +873,13 @@ public abstract class DebugProcessImpl implements DebugProcess { return suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD ? ObjectReference.INVOKE_SINGLE_THREADED : 0; } + @Override public void waitFor() { LOG.assertTrue(!DebuggerManagerThreadImpl.isManagerThread()); myWaitFor.waitFor(); } + @Override public void waitFor(long timeout) { LOG.assertTrue(!DebuggerManagerThreadImpl.isManagerThread()); myWaitFor.waitFor(timeout); @@ -1002,6 +1009,7 @@ public abstract class DebugProcessImpl implements DebugProcess { final Exception[] exception = new Exception[1]; final Value[] result = new Value[1]; getManagerThread().startLongProcessAndFork(new Runnable() { + @Override public void run() { ThreadReferenceProxyImpl thread = context.getThread(); try { @@ -1075,14 +1083,17 @@ public abstract class DebugProcessImpl implements DebugProcess { } } + @Override public Value invokeMethod(final EvaluationContext evaluationContext, final ObjectReference objRef, final Method method, final List args) throws EvaluateException { return invokeInstanceMethod(evaluationContext, objRef, method, args, 0); } + @Override public Value invokeInstanceMethod(final EvaluationContext evaluationContext, final ObjectReference objRef, final Method method, final List args, final int invocationOptions) throws EvaluateException { final ThreadReference thread = getEvaluationThread(evaluationContext); return new InvokeCommand<Value>(args) { + @Override protected Value invokeMethod(int invokePolicy, final List args) throws InvocationException, ClassNotLoadedException, IncompatibleThreadStateException, InvalidTypeException { if (LOG.isDebugEnabled()) { LOG.debug("Invoke " + method.name()); @@ -1100,12 +1111,14 @@ public abstract class DebugProcessImpl implements DebugProcess { return evaluationThread.getThreadReference(); } + @Override public Value invokeMethod(final EvaluationContext evaluationContext, final ClassType classType, final Method method, final List args) throws EvaluateException { final ThreadReference thread = getEvaluationThread(evaluationContext); InvokeCommand<Value> invokeCommand = new InvokeCommand<Value>(args) { + @Override protected Value invokeMethod(int invokePolicy, final List args) throws InvocationException, ClassNotLoadedException, IncompatibleThreadStateException, @@ -1119,17 +1132,20 @@ public abstract class DebugProcessImpl implements DebugProcess { return invokeCommand.start((EvaluationContextImpl)evaluationContext, method); } + @Override public ArrayReference newInstance(final ArrayType arrayType, final int dimension) throws EvaluateException { return arrayType.newInstance(dimension); } + @Override public ObjectReference newInstance(final EvaluationContext evaluationContext, final ClassType classType, final Method method, final List args) throws EvaluateException { final ThreadReference thread = getEvaluationThread(evaluationContext); InvokeCommand<ObjectReference> invokeCommand = new InvokeCommand<ObjectReference>(args) { + @Override protected ObjectReference invokeMethod(int invokePolicy, final List args) throws InvocationException, ClassNotLoadedException, IncompatibleThreadStateException, @@ -1181,6 +1197,7 @@ public abstract class DebugProcessImpl implements DebugProcess { showStatusText(""); } + @Override public ReferenceType findClass(EvaluationContext evaluationContext, String className, ClassLoaderReference classLoader) throws EvaluateException { try { @@ -1255,7 +1272,7 @@ public abstract class DebugProcessImpl implements DebugProcess { } } - @SuppressWarnings({"HardCodedStringLiteral"}) + @SuppressWarnings({"HardCodedStringLiteral", "SpellCheckingInspection"}) public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String qName, ClassLoaderReference classLoader) throws InvocationException, ClassNotLoadedException, IncompatibleThreadStateException, InvalidTypeException, EvaluateException { @@ -1308,13 +1325,15 @@ public abstract class DebugProcessImpl implements DebugProcess { return mySuspendManager; } + @Override public CompoundPositionManager getPositionManager() { return myPositionManager; } //ManagerCommands + @Override public void stop(boolean forceTerminate) { - this.getManagerThread().terminateAndInvoke(createStopCommand(forceTerminate), DebuggerManagerThreadImpl.COMMAND_TIMEOUT); + getManagerThread().terminateAndInvoke(createStopCommand(forceTerminate), DebuggerManagerThreadImpl.COMMAND_TIMEOUT); } public StopCommand createStopCommand(boolean forceTerminate) { @@ -1328,10 +1347,12 @@ public abstract class DebugProcessImpl implements DebugProcess { myIsTerminateTargetVM = isTerminateTargetVM; } + @Override public Priority getPriority() { return Priority.HIGH; } + @Override protected void action() throws Exception { if (isAttached()) { final VirtualMachineProxyImpl virtualMachineProxy = getVirtualMachineProxy(); @@ -1339,8 +1360,7 @@ public abstract class DebugProcessImpl implements DebugProcess { virtualMachineProxy.exit(-1); } else { - // some VM's (like IBM VM 1.4.2 bundled with WebSpere) does not - // resume threads on dispose() like it should + // some VMs (like IBM VM 1.4.2 bundled with WebSphere) does not resume threads on dispose() like it should try { virtualMachineProxy.resume(); } @@ -1360,6 +1380,7 @@ public abstract class DebugProcessImpl implements DebugProcess { super(suspendContext); } + @Override public void contextAction() { showStatusText(DebuggerBundle.message("status.step.out")); final SuspendContextImpl suspendContext = getSuspendContext(); @@ -1391,6 +1412,7 @@ public abstract class DebugProcessImpl implements DebugProcess { null; } + @Override public void contextAction() { showStatusText(DebuggerBundle.message("status.step.into")); final SuspendContextImpl suspendContext = getSuspendContext(); @@ -1409,7 +1431,7 @@ public abstract class DebugProcessImpl implements DebugProcess { hint.setIgnoreFilters(myForcedIgnoreFilters || mySession.shouldIgnoreSteppingFilters()); applyThreadFilter(stepThread); if (myBreakpoint != null) { - myBreakpoint.SUSPEND_POLICY = suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD? DebuggerSettings.SUSPEND_THREAD : DebuggerSettings.SUSPEND_ALL; + myBreakpoint.setSuspendPolicy(suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD? DebuggerSettings.SUSPEND_THREAD : DebuggerSettings.SUSPEND_ALL); myBreakpoint.createRequest(suspendContext.getDebugProcess()); myRunToCursorBreakpoint = myBreakpoint; } @@ -1426,11 +1448,12 @@ public abstract class DebugProcessImpl implements DebugProcess { myIsIgnoreBreakpoints = ignoreBreakpoints; } + @Override public void contextAction() { showStatusText(DebuggerBundle.message("status.step.over")); final SuspendContextImpl suspendContext = getSuspendContext(); final ThreadReferenceProxyImpl stepThread = getContextThread(); - // need this hint whil stepping over for JSR45 support: + // need this hint while stepping over for JSR45 support: // several lines of generated java code may correspond to a single line in the source file, // from which the java code was generated RequestHint hint = new RequestHint(stepThread, suspendContext, StepRequest.STEP_OVER); @@ -1464,6 +1487,7 @@ public abstract class DebugProcessImpl implements DebugProcess { myRunToCursorBreakpoint = breakpointManager.addRunToCursorBreakpoint(document, lineIndex, ignoreBreakpoints); } + @Override public void contextAction() { showStatusText(DebuggerBundle.message("status.run.to.cursor")); cancelRunToCursorBreakpoint(); @@ -1476,8 +1500,7 @@ public abstract class DebugProcessImpl implements DebugProcess { } applyThreadFilter(getContextThread()); final SuspendContextImpl context = getSuspendContext(); - myRunToCursorBreakpoint.SUSPEND_POLICY = context.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD? DebuggerSettings.SUSPEND_THREAD : DebuggerSettings.SUSPEND_ALL; - myRunToCursorBreakpoint.LOG_ENABLED = false; + myRunToCursorBreakpoint.setSuspendPolicy(context.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD? DebuggerSettings.SUSPEND_THREAD : DebuggerSettings.SUSPEND_ALL); myRunToCursorBreakpoint.createRequest(context.getDebugProcess()); DebugProcessImpl.this.myRunToCursorBreakpoint = myRunToCursorBreakpoint; super.contextAction(); @@ -1494,10 +1517,12 @@ public abstract class DebugProcessImpl implements DebugProcess { myContextThread = contextThread != null ? contextThread : (suspendContext != null? suspendContext.getThread() : null); } + @Override public Priority getPriority() { return Priority.HIGH; } + @Override public void contextAction() { showStatusText(DebuggerBundle.message("status.process.resumed")); getSuspendManager().resume(getSuspendContext()); @@ -1524,6 +1549,7 @@ public abstract class DebugProcessImpl implements DebugProcess { public PauseCommand() { } + @Override public void action() { if (!isAttached() || getVirtualMachineProxy().isPausePressed()) { return; @@ -1544,6 +1570,7 @@ public abstract class DebugProcessImpl implements DebugProcess { myThread = thread; } + @Override public void contextAction() { if (getSuspendManager().isFrozen(myThread)) { getSuspendManager().unfreezeThread(myThread); @@ -1553,7 +1580,7 @@ public abstract class DebugProcessImpl implements DebugProcess { final Set<SuspendContextImpl> suspendingContexts = SuspendManagerUtil.getSuspendingContexts(getSuspendManager(), myThread); for (SuspendContextImpl suspendContext : suspendingContexts) { if (suspendContext.getThread() == myThread) { - DebugProcessImpl.this.getManagerThread().invoke(createResumeCommand(suspendContext)); + getManagerThread().invoke(createResumeCommand(suspendContext)); } else { getSuspendManager().resumeThread(suspendContext, myThread); @@ -1569,6 +1596,7 @@ public abstract class DebugProcessImpl implements DebugProcess { myThread = thread; } + @Override protected void action() throws Exception { SuspendManager suspendManager = getSuspendManager(); if (!suspendManager.isFrozen(myThread)) { @@ -1585,6 +1613,7 @@ public abstract class DebugProcessImpl implements DebugProcess { myStackFrame = frameProxy; } + @Override public void contextAction() { final ThreadReferenceProxyImpl thread = myStackFrame.threadProxy(); try { @@ -1593,7 +1622,7 @@ public abstract class DebugProcessImpl implements DebugProcess { return; } } - catch (ObjectCollectedException e) { + catch (ObjectCollectedException ignored) { notifyCancelled(); return; } @@ -1606,6 +1635,7 @@ public abstract class DebugProcessImpl implements DebugProcess { if (myStackFrame.isBottom()) { DebuggerInvocationUtil.swingInvokeLater(myProject, new Runnable() { + @Override public void run() { Messages.showMessageDialog(myProject, DebuggerBundle.message("error.pop.bottom.stackframe"), ActionsBundle.actionText(DebuggerActions.POP_FRAME), Messages.getErrorIcon()); } @@ -1618,6 +1648,7 @@ public abstract class DebugProcessImpl implements DebugProcess { } catch (final EvaluateException e) { DebuggerInvocationUtil.swingInvokeLater(myProject, new Runnable() { + @Override public void run() { Messages.showMessageDialog(myProject, DebuggerBundle.message("error.pop.stackframe", e.getLocalizedMessage()), ActionsBundle.actionText(DebuggerActions.POP_FRAME), Messages.getErrorIcon()); } @@ -1630,6 +1661,7 @@ public abstract class DebugProcessImpl implements DebugProcess { } } + @Override @NotNull public GlobalSearchScope getSearchScope() { LOG.assertTrue(mySession != null, "Accessing debug session before its initialization"); @@ -1668,7 +1700,6 @@ public abstract class DebugProcessImpl implements DebugProcess { } // writing to volatile field ensures the other threads will see the right values in non-volatile fields - myDebugProcessStarted = true; if (ApplicationManager.getApplication().isUnitTestMode()) { return myExecutionResult; @@ -1719,6 +1750,7 @@ public abstract class DebugProcessImpl implements DebugProcess { final Ref<Boolean> connectorIsReady = Ref.create(false); myDebugProcessDispatcher.addListener(new DebugProcessAdapter() { + @Override public void connectorIsReady() { connectorIsReady.set(true); semaphore.up(); @@ -1727,7 +1759,8 @@ public abstract class DebugProcessImpl implements DebugProcess { }); - this.getManagerThread().schedule(new DebuggerCommandImpl() { + getManagerThread().schedule(new DebuggerCommandImpl() { + @Override protected void action() { VirtualMachine vm = null; @@ -1744,7 +1777,7 @@ public abstract class DebugProcessImpl implements DebugProcess { try { wait(500); } - catch (InterruptedException ie) { + catch (InterruptedException ignored) { break; } } @@ -1752,10 +1785,11 @@ public abstract class DebugProcessImpl implements DebugProcess { else { fail(); if (myExecutionResult != null || !connectorIsReady.get()) { - // propagate exception only in case we succeded to obtain execution result, + // propagate exception only in case we succeeded to obtain execution result, // otherwise if the error is induced by the fact that there is nothing to debug, and there is no need to show // this problem to the user SwingUtilities.invokeLater(new Runnable() { + @Override public void run() { ExecutionUtil.handleExecutionError(myProject, ToolWindowId.DEBUG, sessionName, e); } @@ -1773,8 +1807,10 @@ public abstract class DebugProcessImpl implements DebugProcess { if (vm != null) { final VirtualMachine vm1 = vm; afterProcessStarted(new Runnable() { + @Override public void run() { getManagerThread().schedule(new DebuggerCommandImpl() { + @Override protected void action() throws Exception { commitVM(vm1); } @@ -1784,6 +1820,7 @@ public abstract class DebugProcessImpl implements DebugProcess { } } + @Override protected void commandCancelled() { try { super.commandCancelled(); @@ -1809,6 +1846,7 @@ public abstract class DebugProcessImpl implements DebugProcess { removeProcessListener(this); } + @Override public void startNotified(ProcessEvent event) { run(); } @@ -1838,11 +1876,13 @@ public abstract class DebugProcessImpl implements DebugProcess { public ResumeCommand createResumeCommand(SuspendContextImpl suspendContext, final PrioritizedTask.Priority priority) { final BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(getProject()).getBreakpointManager(); return new ResumeCommand(suspendContext) { + @Override public void contextAction() { breakpointManager.applyThreadFilter(DebugProcessImpl.this, null); // clear the filter on resume super.contextAction(); } + @Override public Priority getPriority() { return priority; } @@ -1889,6 +1929,7 @@ public abstract class DebugProcessImpl implements DebugProcess { public void setBreakpointsMuted(final boolean muted) { if (isAttached()) { getManagerThread().schedule(new DebuggerCommandImpl() { + @Override protected void action() throws Exception { // set the flag before enabling/disabling cause it affects if breakpoints will create requests if (myBreakpointsMuted.getAndSet(muted) != muted) { diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/requests/LocatableEventRequestor.java b/java/debugger/impl/src/com/intellij/debugger/engine/requests/LocatableEventRequestor.java index db64d1d1b553..ed1d7af2e16f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/requests/LocatableEventRequestor.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/requests/LocatableEventRequestor.java @@ -19,16 +19,9 @@ import com.intellij.debugger.engine.events.SuspendContextCommandImpl; import com.intellij.debugger.requests.Requestor; import com.sun.jdi.event.LocatableEvent; -/** - * Created by IntelliJ IDEA. - * User: lex - * Date: Jun 27, 2003 - * Time: 8:05:52 PM - * To change this template use Options | File Templates. - */ public interface LocatableEventRequestor extends Requestor { /** - * @returns true if requesto was hit by the event, false otherwise + * @returns true if request was hit by the event, false otherwise */ boolean processLocatableEvent(SuspendContextCommandImpl action, LocatableEvent event) throws EventProcessingException; diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java index 832958759964..c35c971c5a76 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java @@ -30,9 +30,7 @@ import com.intellij.debugger.settings.DebuggerSettings; import com.intellij.debugger.ui.breakpoints.Breakpoint; import com.intellij.debugger.ui.breakpoints.BreakpointManager; import com.intellij.debugger.ui.breakpoints.FilteredRequestor; -import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; @@ -40,15 +38,10 @@ import com.intellij.openapi.util.Key; import com.intellij.psi.PsiClass; import com.intellij.ui.classFilter.ClassFilter; import com.intellij.util.containers.HashMap; -import com.intellij.xdebugger.XDebuggerManager; -import com.intellij.xdebugger.breakpoints.XBreakpointProperties; -import com.intellij.xdebugger.breakpoints.XLineBreakpoint; import com.sun.jdi.*; import com.sun.jdi.event.ClassPrepareEvent; import com.sun.jdi.request.*; import org.jetbrains.annotations.Nullable; -import org.jetbrains.java.debugger.breakpoints.JavaBreakpointAdapter; -import org.jetbrains.java.debugger.breakpoints.JavaBreakpointType; import java.util.Collections; import java.util.HashSet; @@ -158,11 +151,11 @@ public class RequestManagerImpl extends DebugProcessAdapterImpl implements Reque request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); } - if (requestor.COUNT_FILTER_ENABLED && requestor.COUNT_FILTER > 0) { - request.addCountFilter(requestor.COUNT_FILTER); + if (requestor.isCountFilterEnabled() && requestor.getCountFilter() > 0) { + request.addCountFilter(requestor.getCountFilter()); } - if (requestor.CLASS_FILTERS_ENABLED && !(request instanceof BreakpointRequest) /*no built-in class filters support for breakpoint requests*/ ) { + if (requestor.isClassFiltersEnabled() && !(request instanceof BreakpointRequest) /*no built-in class filters support for breakpoint requests*/ ) { ClassFilter[] classFilters = requestor.getClassFilters(); if (DebuggerUtilsEx.getEnabledNumber(classFilters) == 1) { for (final ClassFilter filter : classFilters) { @@ -408,17 +401,18 @@ public class RequestManagerImpl extends DebugProcessAdapterImpl implements Reque breakpoint.createRequest(myDebugProcess); } - AccessToken token = ReadAction.start(); - try { - JavaBreakpointAdapter adapter = new JavaBreakpointAdapter(project); - for (XLineBreakpoint<XBreakpointProperties> breakpoint : XDebuggerManager.getInstance(project).getBreakpointManager() - .getBreakpoints(JavaBreakpointType.class)) { - adapter.getOrCreate(breakpoint).createRequest(myDebugProcess); - } - } - finally { - token.finish(); - } + //AccessToken token = ReadAction.start(); + //try { + // JavaBreakpointAdapter adapter = new JavaBreakpointAdapter(project); + // for (XLineBreakpoint breakpoint : XDebuggerManager.getInstance(project).getBreakpointManager() + // .getBreakpoints(JavaLineBreakpointType.class)) { + // //new JavaLineBreakpointRequestor(breakpoint).createRequest(myDebugProcess); + // //adapter.getOrCreate(breakpoint).createRequest(myDebugProcess); + // } + //} + //finally { + // token.finish(); + //} } }); } diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextImpl.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextImpl.java index e35ba834a9b5..640f76cad628 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextImpl.java @@ -42,7 +42,7 @@ import org.jetbrains.annotations.Nullable; public final class DebuggerContextImpl implements DebuggerContext { private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.DebuggerContextImpl"); - public static final DebuggerContextImpl EMPTY_CONTEXT = DebuggerContextImpl.createDebuggerContext((DebuggerSession) null, null, null, null); + public static final DebuggerContextImpl EMPTY_CONTEXT = createDebuggerContext((DebuggerSession)null, null, null, null); private boolean myInitialized; @@ -58,7 +58,7 @@ public final class DebuggerContextImpl implements DebuggerContext { private DebuggerContextImpl(@Nullable DebuggerSession session, DebugProcessImpl debugProcess, SuspendContextImpl context, ThreadReferenceProxyImpl threadProxy, StackFrameProxyImpl frameProxy, SourcePosition position, PsiElement contextElement, boolean initialized) { LOG.assertTrue(frameProxy == null || threadProxy == null || threadProxy == frameProxy.threadProxy()); - LOG.assertTrue(debugProcess == null ? frameProxy == null && threadProxy == null : true); + LOG.assertTrue(debugProcess != null || frameProxy == null && threadProxy == null); myDebuggerSession = session; myThreadProxy = threadProxy; myFrameProxy = frameProxy; @@ -74,6 +74,7 @@ public final class DebuggerContextImpl implements DebuggerContext { return myDebuggerSession; } + @Override public DebugProcessImpl getDebugProcess() { return myDebugProcess; } @@ -82,14 +83,17 @@ public final class DebuggerContextImpl implements DebuggerContext { return myThreadProxy; } + @Override public SuspendContextImpl getSuspendContext() { return mySuspendContext; } + @Override public Project getProject() { return myDebugProcess != null ? myDebugProcess.getProject() : null; } + @Override @Nullable public StackFrameProxyImpl getFrameProxy() { LOG.assertTrue(myInitialized); @@ -144,13 +148,14 @@ public final class DebuggerContextImpl implements DebuggerContext { try { myFrameProxy = myThreadProxy.frameCount() > 0 ? myThreadProxy.frame(0) : null; } - catch (EvaluateException e) { + catch (EvaluateException ignored) { } } } if(myFrameProxy != null) { PsiDocumentManager.getInstance(getProject()).commitAndRunReadAction(new Runnable() { + @Override public void run() { if (mySourcePosition == null) { mySourcePosition = ContextUtil.getSourcePosition(DebuggerContextImpl.this); 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 917dba29b5a8..7837eab31aa8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java @@ -16,7 +16,6 @@ package com.intellij.debugger.impl; import com.intellij.debugger.*; -import com.intellij.debugger.actions.DebuggerActions; import com.intellij.debugger.engine.*; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluationListener; @@ -56,6 +55,7 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.unscramble.ThreadState; import com.intellij.util.Alarm; import com.intellij.xdebugger.AbstractDebuggerSession; +import com.intellij.xdebugger.impl.actions.XDebuggerActions; import com.intellij.xdebugger.impl.evaluate.quick.common.ValueLookupManager; import com.sun.jdi.ObjectCollectedException; import com.sun.jdi.ThreadReference; @@ -115,6 +115,7 @@ public class DebuggerSession implements AbstractDebuggerSession { @NotNull public GlobalSearchScope getSearchScope() { + //noinspection ConstantConditions LOG.assertTrue(mySearchScope != null, "Accessing Session's search scope before its initialization"); return mySearchScope; } @@ -134,6 +135,7 @@ public class DebuggerSession implements AbstractDebuggerSession { myDebuggerContext = SESSION_EMPTY_CONTEXT; } + @Override public DebuggerContextImpl getContext() { return myDebuggerContext; } @@ -146,11 +148,13 @@ public class DebuggerSession implements AbstractDebuggerSession { * in this case we assume that the latter setState is ignored * since the thread was resumed */ + @Override public void setState(final DebuggerContextImpl context, final int state, final int event, final String description) { ApplicationManager.getApplication().assertIsDispatchThread(); final DebuggerSession session = context.getDebuggerSession(); LOG.assertTrue(session == DebuggerSession.this || session == null); final Runnable setStateRunnable = new Runnable() { + @Override public void run() { LOG.assertTrue(myDebuggerContext.isInitialised()); myDebuggerContext = context; @@ -170,6 +174,7 @@ public class DebuggerSession implements AbstractDebuggerSession { } else { getProcess().getManagerThread().schedule(new SuspendContextCommandImpl(context.getSuspendContext()) { + @Override public void contextAction() throws Exception { context.initCaches(); DebuggerInvocationUtil.swingInvokeLater(getProject(), setStateRunnable); @@ -279,7 +284,7 @@ public class DebuggerSession implements AbstractDebuggerSession { resumeAction(runToCursorCommand, EVENT_STEP); } catch (EvaluateException e) { - Messages.showErrorDialog(e.getMessage(), ActionsBundle.actionText(DebuggerActions.RUN_TO_CURSOR)); + Messages.showErrorDialog(e.getMessage(), ActionsBundle.actionText(XDebuggerActions.RUN_TO_CURSOR)); } } @@ -335,6 +340,7 @@ public class DebuggerSession implements AbstractDebuggerSession { } // ManagerCommands + @Override public boolean isStopped() { return getState() == STATE_STOPPED; } @@ -343,6 +349,7 @@ public class DebuggerSession implements AbstractDebuggerSession { return !isStopped() && getState() != STATE_WAITING_ATTACH; } + @Override public boolean isPaused() { return getState() == STATE_PAUSED; } @@ -399,18 +406,21 @@ public class DebuggerSession implements AbstractDebuggerSession { } //executed in manager thread + @Override public void connectorIsReady() { DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + @Override public void run() { RemoteConnection connection = myDebugProcess.getConnection(); final String addressDisplayName = DebuggerBundle.getAddressDisplayName(connection); final String transportName = DebuggerBundle.getTransportName(connection); final String connectionStatusMessage = connection.isServerMode() ? DebuggerBundle.message("status.listening", addressDisplayName, transportName) : DebuggerBundle.message("status.connecting", addressDisplayName, transportName); - getContextManager().setState(SESSION_EMPTY_CONTEXT, DebuggerSession.STATE_WAITING_ATTACH, DebuggerSession.EVENT_START_WAIT_ATTACH, connectionStatusMessage); + getContextManager().setState(SESSION_EMPTY_CONTEXT, STATE_WAITING_ATTACH, EVENT_START_WAIT_ATTACH, connectionStatusMessage); } }); } + @Override public void paused(final SuspendContextImpl suspendContext) { if (LOG.isDebugEnabled()) { LOG.debug("paused"); @@ -418,6 +428,7 @@ public class DebuggerSession implements AbstractDebuggerSession { if (!shouldSetAsActiveContext(suspendContext)) { DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + @Override public void run() { getContextManager().fireStateChanged(getContextManager().getContext(), EVENT_THREADS_REFRESH); } @@ -470,7 +481,7 @@ public class DebuggerSession implements AbstractDebuggerSession { } proxy = (currentThread.frameCount() > 0) ? currentThread.frame(0) : null; } - catch (ObjectCollectedException e) { + catch (ObjectCollectedException ignored) { proxy = null; } catch (EvaluateException e) { @@ -498,6 +509,7 @@ public class DebuggerSession implements AbstractDebuggerSession { } SourcePosition position = PsiDocumentManager.getInstance(getProject()).commitAndRunReadAction(new Computable<SourcePosition>() { + @Override public @Nullable SourcePosition compute() { return ContextUtil.getSourcePosition(positionContext); } @@ -507,7 +519,7 @@ public class DebuggerSession implements AbstractDebuggerSession { final List<Pair<Breakpoint, Event>> eventDescriptors = DebuggerUtilsEx.getEventDescriptors(suspendContext); final RequestManagerImpl requestsManager = suspendContext.getDebugProcess().getRequestsManager(); final PsiFile foundFile = position.getFile(); - final boolean sourceMissing = foundFile == null || foundFile instanceof PsiCompiledElement; + final boolean sourceMissing = foundFile instanceof PsiCompiledElement; for (Pair<Breakpoint, Event> eventDescriptor : eventDescriptors) { Breakpoint breakpoint = eventDescriptor.getFirst(); if (breakpoint instanceof LineBreakpoint) { @@ -525,7 +537,7 @@ public class DebuggerSession implements AbstractDebuggerSession { try { className = frameProxy != null? frameProxy.location().declaringType().name() : ""; } - catch (EvaluateException e) { + catch (EvaluateException ignored) { className = ""; } requestsManager.setInvalid(breakpoint, DebuggerBundle.message("error.invalid.breakpoint.source.not.found", className)); @@ -539,6 +551,7 @@ public class DebuggerSession implements AbstractDebuggerSession { debuggerContext.setPositionCache(position); DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + @Override public void run() { getContextManager().setState(debuggerContext, STATE_PAUSED, EVENT_PAUSE, null); } @@ -562,9 +575,11 @@ public class DebuggerSession implements AbstractDebuggerSession { } + @Override public void resumed(final SuspendContextImpl suspendContext) { final SuspendContextImpl currentContext = getProcess().getSuspendManager().getPausedContext(); DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + @Override public void run() { if (currentContext != null) { getContextManager().setState(DebuggerContextUtil.createDebuggerContext(DebuggerSession.this, currentContext), STATE_PAUSED, EVENT_CONTEXT, null); @@ -576,6 +591,7 @@ public class DebuggerSession implements AbstractDebuggerSession { }); } + @Override public void processAttached(final DebugProcessImpl process) { final RemoteConnection connection = getProcess().getConnection(); final String addressDisplayName = DebuggerBundle.getAddressDisplayName(connection); @@ -584,14 +600,17 @@ public class DebuggerSession implements AbstractDebuggerSession { process.getExecutionResult().getProcessHandler().notifyTextAvailable(message + "\n", ProcessOutputTypes.SYSTEM); DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + @Override public void run() { getContextManager().setState(SESSION_EMPTY_CONTEXT, STATE_RUNNING, EVENT_ATTACHED, message); } }); } + @Override public void attachException(final RunProfileState state, final ExecutionException exception, final RemoteConnection remoteConnection) { DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + @Override public void run() { String message = ""; if (state instanceof RemoteState) { @@ -603,6 +622,7 @@ public class DebuggerSession implements AbstractDebuggerSession { }); } + @Override public void processDetached(final DebugProcessImpl debugProcess, boolean closedByUser) { if (!closedByUser) { ExecutionResult executionResult = debugProcess.getExecutionResult(); @@ -614,6 +634,7 @@ public class DebuggerSession implements AbstractDebuggerSession { } } DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + @Override public void run() { final RemoteConnection connection = getProcess().getConnection(); final String addressDisplayName = DebuggerBundle.getAddressDisplayName(connection); @@ -624,10 +645,12 @@ public class DebuggerSession implements AbstractDebuggerSession { mySteppingThroughThreads.clear(); } + @Override public void threadStarted(DebugProcess proc, ThreadReference thread) { notifyThreadsRefresh(); } + @Override public void threadStopped(DebugProcess proc, ThreadReference thread) { notifyThreadsRefresh(); } @@ -636,6 +659,7 @@ public class DebuggerSession implements AbstractDebuggerSession { if (!myUpdateAlarm.isDisposed()) { myUpdateAlarm.cancelAllRequests(); myUpdateAlarm.addRequest(new Runnable() { + @Override public void run() { final DebuggerStateManager contextManager = getContextManager(); contextManager.fireStateChanged(contextManager.getContext(), EVENT_THREADS_REFRESH); @@ -646,13 +670,16 @@ public class DebuggerSession implements AbstractDebuggerSession { } private class MyEvaluationListener implements EvaluationListener { + @Override public void evaluationStarted(SuspendContextImpl context) { myIsEvaluating = true; } + @Override public void evaluationFinished(final SuspendContextImpl context) { myIsEvaluating = false; DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + @Override public void run() { if (context != getSuspendContext()) { getContextManager().setState(DebuggerContextUtil.createDebuggerContext(DebuggerSession.this, context), STATE_PAUSED, EVENT_REFRESH, null); diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java index 4ff1adcabda4..5fed47929af3 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java @@ -70,7 +70,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { clearCaches(); } catch (InternalException e) { - if (e.errorCode() == 23 /*INVALID_METHODID accoeding to JDI sources*/) { + if (e.errorCode() == 23 /*INVALID_METHODID according to JDI sources*/) { myIsObsolete = Boolean.TRUE; return true; } @@ -83,6 +83,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { return false; } + @Override protected void clearCaches() { DebuggerManagerThreadImpl.assertIsManagerThread(); if (LOG.isDebugEnabled()) { @@ -100,6 +101,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { * Use with caution. Better access stackframe data through the Proxy's methods */ + @Override public StackFrame getStackFrame() throws EvaluateException { DebuggerManagerThreadImpl.assertIsManagerThread(); @@ -113,7 +115,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { catch (IndexOutOfBoundsException e) { throw new EvaluateException(e.getMessage(), e); } - catch (ObjectCollectedException e) { + catch (ObjectCollectedException ignored) { throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.thread.collected")); } catch (IncompatibleThreadStateException e) { @@ -124,6 +126,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { return myStackFrame; } + @Override public int getFrameIndex() throws EvaluateException { DebuggerManagerThreadImpl.assertIsManagerThread(); checkValid(); @@ -151,10 +154,13 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { // return false; // } + @Override public VirtualMachineProxyImpl getVirtualMachine() { return (VirtualMachineProxyImpl) myTimer; } + @Nullable + @Override public Location location() throws EvaluateException { InvalidStackFrameException error = null; for (int attempt = 0; attempt < 2; attempt++) { @@ -172,6 +178,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { return null; } + @Override public ThreadReferenceProxyImpl threadProxy() { return myThreadProxy; } @@ -197,13 +204,13 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { } break; } - catch (InvalidStackFrameException e) { + catch (InvalidStackFrameException ignored) { clearCaches(); } } } catch (InternalException e) { - // supress some internal errors caused by bugs in specific JDI implementations + // suppress some internal errors caused by bugs in specific JDI implementations if(e.errorCode() != 23) { throw EvaluateExceptionUtil.createEvaluateException(e); } @@ -238,6 +245,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { return Collections.emptyList(); } + @Override public LocalVariableProxyImpl visibleVariableByName(String name) throws EvaluateException { DebuggerManagerThreadImpl.assertIsManagerThread(); final LocalVariable variable = visibleVariableByNameInt(name); @@ -332,7 +340,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { myAllValues.put(variable, value); } } - catch (InconsistentDebugInfoException e) { + catch (InconsistentDebugInfoException ignored) { clearCaches(); throw EvaluateExceptionUtil.INCONSISTEND_DEBUG_INFO; } @@ -388,12 +396,13 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { try { return var.getVariable().isVisible(getStackFrame()); } - catch (IllegalArgumentException e) { + catch (IllegalArgumentException ignored) { // can be thrown if frame's method is different than variable's method return false; } } + @Override public ClassLoaderReference getClassLoader() throws EvaluateException { if(myClassLoader == null) { myClassLoader = location().declaringType().classLoader(); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java index 5eb71c30e869..1395654a06d1 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java @@ -73,8 +73,6 @@ public abstract class DebuggerEditorImpl extends CompletionEditor{ private final JLabel myChooseFactory = new JLabel(); private WeakReference<ListPopup> myPopup; - private boolean myExplicitlyChosen = false; - private final PsiTreeChangeListener myPsiListener = new PsiTreeChangeAdapter() { public void childRemoved(@NotNull PsiTreeChangeEvent event) { checkContext(); @@ -142,7 +140,6 @@ public abstract class DebuggerEditorImpl extends CompletionEditor{ @Override public void actionPerformed(AnActionEvent e) { setFactory(fragmentFactory); - myExplicitlyChosen = true; setText(getText()); IdeFocusManager.getInstance(getProject()).requestFocus(DebuggerEditorImpl.this, true); } @@ -300,33 +297,12 @@ public abstract class DebuggerEditorImpl extends CompletionEditor{ return DefaultCodeFragmentFactory.getInstance(); } - @NotNull - private CodeFragmentFactory findFactoryForRestore(@NotNull TextWithImports text, @NotNull PsiElement context) { - List<CodeFragmentFactory> factories = DebuggerUtilsEx.getCodeFragmentFactories(context); - - if (myExplicitlyChosen && factories.contains(myFactory)) return myFactory; - - DefaultCodeFragmentFactory defaultFactory = DefaultCodeFragmentFactory.getInstance(); - factories.remove(defaultFactory); - for (CodeFragmentFactory factory : factories) { - if (factory.getFileType().equals(text.getFileType())) { - return factory; - } - } - if (!factories.isEmpty()) return factories.get(0); - else return defaultFactory; - } - protected void restoreFactory(TextWithImports text) { FileType fileType = text.getFileType(); if (fileType == null) return; if (myContext == null) return; - CodeFragmentFactory newFactory = findFactoryForRestore(text, myContext); - if (!newFactory.equals(myFactory)) { - myExplicitlyChosen = false; - setFactory(newFactory); - } + setFactory(findAppropriateFactory(text, myContext)); } private void setFactory(@NotNull final CodeFragmentFactory factory) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java index e021d76b271b..46f1515f1ea5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java @@ -19,19 +19,17 @@ import com.intellij.debugger.DebuggerManagerEx; import com.intellij.debugger.actions.*; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.settings.*; -import com.intellij.debugger.ui.breakpoints.*; +import com.intellij.debugger.ui.breakpoints.Breakpoint; import com.intellij.ide.DataManager; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.markup.GutterIconRenderer; -import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.Key; -import com.intellij.util.containers.ContainerUtil; import com.intellij.xdebugger.AbstractDebuggerSession; import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule; import com.intellij.xdebugger.impl.DebuggerSupport; @@ -45,9 +43,10 @@ import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler; import com.intellij.xdebugger.impl.settings.DebuggerSettingsPanelProvider; import org.jetbrains.annotations.NotNull; +import javax.swing.*; +import java.awt.*; import java.util.ArrayList; import java.util.Collection; -import java.util.List; /** * @author nik @@ -63,8 +62,6 @@ public class JavaDebuggerSupport extends DebuggerSupport { private final ForceRunToCursorActionHandler myForceRunToCursorActionHandler = new ForceRunToCursorActionHandler(); private final ResumeActionHandler myResumeActionHandler = new ResumeActionHandler(); private final PauseActionHandler myPauseActionHandler = new PauseActionHandler(); - private final ToggleLineBreakpointActionHandler myToggleLineBreakpointActionHandler = new ToggleLineBreakpointActionHandler(false); - private final ToggleLineBreakpointActionHandler myToggleTemporaryLineBreakpointActionHandler = new ToggleLineBreakpointActionHandler(true); private final ShowExecutionPointActionHandler myShowExecutionPointActionHandler = new ShowExecutionPointActionHandler(); private final EvaluateActionHandler myEvaluateActionHandler = new EvaluateActionHandler(); private final QuickEvaluateActionHandler myQuickEvaluateHandler = new QuickEvaluateActionHandler(); @@ -73,84 +70,98 @@ public class JavaDebuggerSupport extends DebuggerSupport { private final DebuggerActionHandler mySmartStepIntoHandler = new JvmSmartStepIntoActionHandler(); private final DebuggerActionHandler myAddToWatchedActionHandler = new AddToWatchActionHandler(); private final JavaMarkObjectActionHandler myMarkObjectActionHandler = new JavaMarkObjectActionHandler(); - private final JavaEditBreakpointActionHandler myEditBreakpointActionHandler = new JavaEditBreakpointActionHandler(); + @Override @NotNull public BreakpointPanelProvider<?> getBreakpointPanelProvider() { return myBreakpointPanelProvider; } + @Override @NotNull public DebuggerActionHandler getStepOverHandler() { return myStepOverActionHandler; } + @Override @NotNull public DebuggerActionHandler getStepIntoHandler() { return myStepIntoActionHandler; } + @Override @NotNull public DebuggerActionHandler getSmartStepIntoHandler() { return mySmartStepIntoHandler; } + @Override @NotNull public DebuggerActionHandler getStepOutHandler() { return myStepOutActionHandler; } + @Override @NotNull public DebuggerActionHandler getForceStepOverHandler() { return myForceStepOverActionHandler; } + @Override @NotNull public DebuggerActionHandler getForceStepIntoHandler() { return myForceStepIntoActionHandler; } + @Override @NotNull public DebuggerActionHandler getRunToCursorHandler() { return myRunToCursorActionHandler; } + @Override @NotNull public DebuggerActionHandler getForceRunToCursorHandler() { return myForceRunToCursorActionHandler; } + @Override @NotNull public DebuggerActionHandler getResumeActionHandler() { return myResumeActionHandler; } + @Override @NotNull public DebuggerActionHandler getPauseHandler() { return myPauseActionHandler; } + @Override @NotNull public DebuggerActionHandler getToggleLineBreakpointHandler() { - return myToggleLineBreakpointActionHandler; + return DISABLED; } @NotNull @Override public DebuggerActionHandler getToggleTemporaryLineBreakpointHandler() { - return myToggleTemporaryLineBreakpointActionHandler; + return DISABLED; } + @Override @NotNull public DebuggerActionHandler getShowExecutionPointHandler() { return myShowExecutionPointActionHandler; } + @Override @NotNull public DebuggerActionHandler getEvaluateHandler() { return myEvaluateActionHandler; } + @Override @NotNull public QuickEvaluateHandler getQuickEvaluateHandler() { return myQuickEvaluateHandler; @@ -162,6 +173,7 @@ public class JavaDebuggerSupport extends DebuggerSupport { return myAddToWatchedActionHandler; } + @Override @NotNull public DebuggerToggleActionHandler getMuteBreakpointsHandler() { return myMuteBreakpointsHandler; @@ -182,134 +194,141 @@ public class JavaDebuggerSupport extends DebuggerSupport { @NotNull @Override public EditBreakpointActionHandler getEditBreakpointAction() { - return myEditBreakpointActionHandler; + return DISABLED_EDIT; } + @Override @NotNull public DebuggerSettingsPanelProvider getSettingsPanelProvider() { return myDebuggerSettingsPanelProvider; } private static class JavaBreakpointPanelProvider extends BreakpointPanelProvider<Breakpoint> { - private final List<MyBreakpointManagerListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList(); + //private final List<MyBreakpointManagerListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList(); @Override public AnAction[] getAddBreakpointActions(@NotNull Project project) { - List<AnAction> result = new ArrayList<AnAction>(); - BreakpointFactory[] breakpointFactories = BreakpointFactory.getBreakpointFactories(); - for (BreakpointFactory breakpointFactory : breakpointFactories) { - result.add(new AddJavaBreakpointAction(breakpointFactory)); - } - return result.toArray(new AnAction[result.size()]); + //List<AnAction> result = new ArrayList<AnAction>(); + //BreakpointFactory[] breakpointFactories = BreakpointFactory.getBreakpointFactories(); + //for (BreakpointFactory breakpointFactory : breakpointFactories) { + // result.add(new AddJavaBreakpointAction(breakpointFactory)); + //} + //return result.toArray(new AnAction[result.size()]); + return AnAction.EMPTY_ARRAY; } @Override public void createBreakpointsGroupingRules(Collection<XBreakpointGroupingRule> rules) { - rules.add(new XBreakpointGroupingByCategoryRule()); + //rules.add(new XBreakpointGroupingByCategoryRule()); rules.add(new XBreakpointGroupingByPackageRule()); rules.add(new XBreakpointGroupingByClassRule()); } @Override public void addListener(final BreakpointsListener listener, Project project, Disposable disposable) { - BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager(); - final MyBreakpointManagerListener listener1 = new MyBreakpointManagerListener(listener, breakpointManager); - breakpointManager.addBreakpointManagerListener(listener1); - myListeners.add(listener1); - Disposer.register(disposable, new Disposable() { - @Override - public void dispose() { - removeListener(listener); - } - }); + //BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager(); + //final MyBreakpointManagerListener listener1 = new MyBreakpointManagerListener(listener, breakpointManager); + //breakpointManager.addBreakpointManagerListener(listener1); + //myListeners.add(listener1); + //Disposer.register(disposable, new Disposable() { + // @Override + // public void dispose() { + // removeListener(listener); + // } + //}); } @Override protected void removeListener(BreakpointsListener listener) { - for (MyBreakpointManagerListener managerListener : myListeners) { - if (managerListener.myListener == listener) { - BreakpointManager manager = managerListener.myBreakpointManager; - manager.removeBreakpointManagerListener(managerListener); - myListeners.remove(managerListener); - break; - } - } + //for (MyBreakpointManagerListener managerListener : myListeners) { + // if (managerListener.myListener == listener) { + // BreakpointManager manager = managerListener.myBreakpointManager; + // manager.removeBreakpointManagerListener(managerListener); + // myListeners.remove(managerListener); + // break; + // } + //} } + @Override public int getPriority() { - return 1; + return 100; } + @Override public Breakpoint findBreakpoint(@NotNull final Project project, @NotNull final Document document, final int offset) { - return DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().findBreakpoint(document, offset, null); + return null; + //return DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().findBreakpoint(document, offset, null); } @Override public GutterIconRenderer getBreakpointGutterIconRenderer(Object breakpoint) { - if (breakpoint instanceof BreakpointWithHighlighter) { - final RangeHighlighter highlighter = ((BreakpointWithHighlighter)breakpoint).getHighlighter(); - if (highlighter != null) { - return (GutterIconRenderer)highlighter.getGutterIconRenderer(); - } - } + //if (breakpoint instanceof BreakpointWithHighlighter) { + // final RangeHighlighter highlighter = ((BreakpointWithHighlighter)breakpoint).getHighlighter(); + // if (highlighter != null) { + // return (GutterIconRenderer)highlighter.getGutterIconRenderer(); + // } + //} return null; } + @Override public void onDialogClosed(final Project project) { - DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().updateAllRequests(); + //DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().updateAllRequests(); } @Override public void provideBreakpointItems(Project project, Collection<BreakpointItem> items) { - for (BreakpointFactory breakpointFactory : BreakpointFactory.getBreakpointFactories()) { - Key<? extends Breakpoint> category = breakpointFactory.getBreakpointCategory(); - Breakpoint[] breakpoints = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().getBreakpoints(category); - for (Breakpoint breakpoint : breakpoints) { - items.add(breakpointFactory.createBreakpointItem(breakpoint)); - } - } + //for (BreakpointFactory breakpointFactory : BreakpointFactory.getBreakpointFactories()) { + // Key<? extends Breakpoint> category = breakpointFactory.getBreakpointCategory(); + // Breakpoint[] breakpoints = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().getBreakpoints(category); + // for (Breakpoint breakpoint : breakpoints) { + // items.add(breakpointFactory.createBreakpointItem(breakpoint)); + // } + //} } - private static class AddJavaBreakpointAction extends AnAction { - private BreakpointFactory myBreakpointFactory; - - public AddJavaBreakpointAction(BreakpointFactory breakpointFactory) { - myBreakpointFactory = breakpointFactory; - Presentation p = getTemplatePresentation(); - p.setIcon(myBreakpointFactory.getIcon()); - p.setText(breakpointFactory.getDisplayName()); - } - - @Override - public void update(AnActionEvent e) { - e.getPresentation().setVisible(myBreakpointFactory.canAddBreakpoints()); - } - - @Override - public void actionPerformed(AnActionEvent e) { - myBreakpointFactory.addBreakpoint(getEventProject(e)); - } - } - - private static class MyBreakpointManagerListener implements BreakpointManagerListener { - - private final BreakpointsListener myListener; - public BreakpointManager myBreakpointManager; - - - public MyBreakpointManagerListener(BreakpointsListener listener, BreakpointManager breakpointManager) { - myListener = listener; - myBreakpointManager = breakpointManager; - } - - @Override - public void breakpointsChanged() { - myListener.breakpointsChanged(); - } - } + //private static class AddJavaBreakpointAction extends AnAction { + // private BreakpointFactory myBreakpointFactory; + // + // public AddJavaBreakpointAction(BreakpointFactory breakpointFactory) { + // myBreakpointFactory = breakpointFactory; + // Presentation p = getTemplatePresentation(); + // p.setIcon(myBreakpointFactory.getIcon()); + // p.setText(breakpointFactory.getDisplayName()); + // } + // + // @Override + // public void update(AnActionEvent e) { + // e.getPresentation().setVisible(myBreakpointFactory.canAddBreakpoints()); + // } + // + // @Override + // public void actionPerformed(AnActionEvent e) { + // myBreakpointFactory.addBreakpoint(getEventProject(e)); + // } + //} + + //private static class MyBreakpointManagerListener implements BreakpointManagerListener { + // + // private final BreakpointsListener myListener; + // public BreakpointManager myBreakpointManager; + // + // + // public MyBreakpointManagerListener(BreakpointsListener listener, BreakpointManager breakpointManager) { + // myListener = listener; + // myBreakpointManager = breakpointManager; + // } + // + // @Override + // public void breakpointsChanged() { + // myListener.breakpointsChanged(); + // } + //} } public static class JavaDebuggerSettingsPanelProvider extends DebuggerSettingsPanelProvider { + @Override public int getPriority() { return 1; } @@ -319,6 +338,7 @@ public class JavaDebuggerSupport extends DebuggerSupport { return new DebuggerLaunchingConfigurable(); } + @Override public Collection<? extends Configurable> getConfigurables() { final ArrayList<Configurable> configurables = new ArrayList<Configurable>(); configurables.add(new DebuggerDataViewsConfigurable(null)); @@ -328,6 +348,7 @@ public class JavaDebuggerSupport extends DebuggerSupport { return configurables; } + @Override public void apply() { NodeRendererSettings.getInstance().fireRenderersChanged(); } @@ -341,4 +362,27 @@ public class JavaDebuggerSupport extends DebuggerSupport { } return ProjectManager.getInstance().getDefaultProject(); } + + private static final DebuggerActionHandler DISABLED = new DebuggerActionHandler() { + @Override + public void perform(@NotNull Project project, AnActionEvent event) { + } + + @Override + public boolean isEnabled(@NotNull Project project, AnActionEvent event) { + return false; + } + }; + + private static final EditBreakpointActionHandler DISABLED_EDIT = new EditBreakpointActionHandler() { + @Override + protected void doShowPopup(Project project, JComponent component, Point whereToShow, Object breakpoint) { + + } + + @Override + public boolean isEnabled(@NotNull Project project, AnActionEvent event) { + return false; + } + }; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/PositionHighlighter.java b/java/debugger/impl/src/com/intellij/debugger/ui/PositionHighlighter.java index e5bb8faafb61..dd0b0de43151 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/PositionHighlighter.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/PositionHighlighter.java @@ -437,7 +437,7 @@ public class PositionHighlighter { public void actionPerformed(AnActionEvent e) { if (myEventsOutOfLine.size() == 1) { Breakpoint breakpoint = myEventsOutOfLine.get(0).getFirst(); - breakpoint.ENABLED = !breakpoint.ENABLED; + breakpoint.setEnabled(!breakpoint.isEnabled()); DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().fireBreakpointChanged(breakpoint); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointCategoryGroup.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointCategoryGroup.java deleted file mode 100644 index 032b480c5584..000000000000 --- a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointCategoryGroup.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.debugger.ui; - -import com.intellij.debugger.ui.breakpoints.Breakpoint; -import com.intellij.debugger.ui.breakpoints.BreakpointFactory; -import com.intellij.openapi.util.Key; -import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroup; -import com.intellij.xdebugger.impl.breakpoints.ui.grouping.XBreakpointTypeGroup; -import org.jetbrains.annotations.NotNull; - -import javax.swing.*; - -/** - * Created with IntelliJ IDEA. - * User: zajac - * Date: 23.05.12 - * Time: 16:22 - * To change this template use File | Settings | File Templates. - */ -public class XBreakpointCategoryGroup extends XBreakpointGroup { - private Key<? extends Breakpoint> myCategory; - private Icon myIcon; - private final String myName; - - public XBreakpointCategoryGroup(BreakpointFactory factory) { - myCategory = factory.getBreakpointCategory(); - myIcon = factory.getIcon(); - final String name = factory.getDisplayName(); - myName = name != null ? name : "UNKNOWN"; - } - - public Key<? extends Breakpoint> getCategory() { - return myCategory; - } - - @Override - public Icon getIcon(boolean isOpen) { - return myIcon; - } - - @NotNull - @Override - public String getName() { - return myName; - } - - @Override - public int compareTo(XBreakpointGroup o) { - if (o instanceof XBreakpointTypeGroup) { - return -1; - } - if (o instanceof XBreakpointCategoryGroup) { - return getFactoryIndex() - ((XBreakpointCategoryGroup)o).getFactoryIndex(); - } - return super.compareTo(o); - } - - private int getFactoryIndex() { - BreakpointFactory[] breakpointFactories = BreakpointFactory.getBreakpointFactories(); - for (int i = 0; i < breakpointFactories.length; ++i) { - if (breakpointFactories[i].getBreakpointCategory().equals(myCategory)) { - return i; - } - } - return -1; - } -} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByCategoryRule.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByCategoryRule.java deleted file mode 100644 index f9dc88af07ac..000000000000 --- a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByCategoryRule.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.debugger.ui; - -import com.intellij.debugger.ui.breakpoints.AnyExceptionBreakpoint; -import com.intellij.debugger.ui.breakpoints.Breakpoint; -import com.intellij.debugger.ui.breakpoints.BreakpointFactory; -import com.intellij.debugger.ui.breakpoints.ExceptionBreakpoint; -import com.intellij.openapi.util.Key; -import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule; -import com.intellij.xdebugger.breakpoints.ui.XBreakpointsGroupingPriorities; -import org.jetbrains.annotations.NotNull; - -import java.util.Collection; - -class XBreakpointGroupingByCategoryRule<B> extends XBreakpointGroupingRule<B, XBreakpointCategoryGroup> { - XBreakpointGroupingByCategoryRule() { - super("XBreakpointGroupingByCategoryRule", "Type"); - } - - @Override - public boolean isAlwaysEnabled() { - return true; - } - - @Override - public int getPriority() { - return XBreakpointsGroupingPriorities.BY_TYPE; - } - - @Override - public XBreakpointCategoryGroup getGroup(@NotNull B b, @NotNull Collection<XBreakpointCategoryGroup> groups) { - if (b instanceof Breakpoint) { - final Breakpoint breakpoint = (Breakpoint)b; - Key<? extends Breakpoint> category = breakpoint.getCategory(); - if (category.equals(AnyExceptionBreakpoint.ANY_EXCEPTION_BREAKPOINT)) { - category = ExceptionBreakpoint.CATEGORY; - } - for (XBreakpointCategoryGroup group : groups) { - if (group.getCategory().equals(category)) { - return group; - } - } - final BreakpointFactory factory = BreakpointFactory.getInstance(category); - if (factory != null) { - return new XBreakpointCategoryGroup(factory); - } - } - return null; - } -} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java index f06a17ef0727..cebaf68612a0 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java @@ -15,8 +15,11 @@ */ package com.intellij.debugger.ui; +import com.intellij.debugger.DebuggerManagerEx; import com.intellij.debugger.ui.breakpoints.Breakpoint; +import com.intellij.debugger.ui.breakpoints.BreakpointManager; import com.intellij.icons.AllIcons; +import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule; import com.intellij.xdebugger.breakpoints.ui.XBreakpointsGroupingPriorities; import org.jetbrains.annotations.NotNull; @@ -42,10 +45,14 @@ class XBreakpointGroupingByClassRule<B> extends XBreakpointGroupingRule<B, XBrea @Override public XBreakpointClassGroup getGroup(@NotNull B b, @NotNull Collection<XBreakpointClassGroup> groups) { - if (b instanceof Breakpoint) { - final Breakpoint breakpoint = (Breakpoint)b; - String className = breakpoint.getShortClassName(); - String packageName = breakpoint.getPackageName(); + if (b instanceof XBreakpoint) { + BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(JavaDebuggerSupport.getCurrentProject()).getBreakpointManager(); + Breakpoint javaBreakpoint = breakpointManager.findBreakpoint((XBreakpoint)b); + if (javaBreakpoint == null) { + return null; + } + String className = javaBreakpoint.getShortClassName(); + String packageName = javaBreakpoint.getPackageName(); if (className == null) { return null; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java index 5763a3648f64..98ef5a3409ec 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java @@ -15,10 +15,12 @@ */ package com.intellij.debugger.ui; -import com.intellij.debugger.ui.breakpoints.BreakpointWithHighlighter; -import com.intellij.debugger.ui.breakpoints.ExceptionBreakpoint; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.ui.breakpoints.Breakpoint; +import com.intellij.debugger.ui.breakpoints.BreakpointManager; import com.intellij.icons.AllIcons; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule; import com.intellij.xdebugger.breakpoints.ui.XBreakpointsGroupingPriorities; import org.jetbrains.annotations.NotNull; @@ -41,11 +43,12 @@ public class XBreakpointGroupingByPackageRule<B> extends XBreakpointGroupingRule @Override public XBreakpointPackageGroup getGroup(@NotNull B breakpoint, @NotNull Collection<XBreakpointPackageGroup> groups) { String packageName = null; - if (breakpoint instanceof BreakpointWithHighlighter) { - packageName = ((BreakpointWithHighlighter)breakpoint).getPackageName(); - } - else if (breakpoint instanceof ExceptionBreakpoint) { - packageName = ((ExceptionBreakpoint)breakpoint).getPackageName(); + if (breakpoint instanceof XBreakpoint) { + BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(JavaDebuggerSupport.getCurrentProject()).getBreakpointManager(); + Breakpoint javaBreakpoint = breakpointManager.findBreakpoint((XBreakpoint)breakpoint); + if (javaBreakpoint != null) { + packageName = javaBreakpoint.getPackageName(); + } } if (packageName == null) { return null; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddFieldBreakpointDialog.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddFieldBreakpointDialog.java index f325da10fcde..e3cd5229e0ab 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddFieldBreakpointDialog.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddFieldBreakpointDialog.java @@ -41,7 +41,7 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.List; -abstract class AddFieldBreakpointDialog extends DialogWrapper { +public abstract class AddFieldBreakpointDialog extends DialogWrapper { private final Project myProject; private JPanel myPanel; private TextFieldWithBrowseButton myFieldChooser; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddWildcardBreakpointDialog.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddWildcardBreakpointDialog.java index c18acb715935..73c74a4eed0a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddWildcardBreakpointDialog.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddWildcardBreakpointDialog.java @@ -30,7 +30,7 @@ public class AddWildcardBreakpointDialog extends DialogWrapper { private JTextField myClassPatternField; private JTextField myMethodNameField; - protected AddWildcardBreakpointDialog(Project project) { + public AddWildcardBreakpointDialog(Project project) { super(project, true); setTitle("Add Method Breakpoint"); init(); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpoint.java index 3d1ff8507d10..8787290c2f09 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpoint.java @@ -27,6 +27,7 @@ import com.intellij.debugger.engine.DebuggerManagerThreadImpl; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.Key; +import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.sun.jdi.ReferenceType; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -34,9 +35,9 @@ import org.jetbrains.annotations.NonNls; public class AnyExceptionBreakpoint extends ExceptionBreakpoint { public static final @NonNls Key<AnyExceptionBreakpoint> ANY_EXCEPTION_BREAKPOINT = BreakpointCategory.lookup("breakpoint_any"); - protected AnyExceptionBreakpoint(Project project) { - super(project, null, null); - ENABLED = false; + protected AnyExceptionBreakpoint(Project project, XBreakpoint xBreakpoint) { + super(project, null, null, xBreakpoint); + //setEnabled(false); } public Key<AnyExceptionBreakpoint> getCategory() { @@ -49,7 +50,7 @@ public class AnyExceptionBreakpoint extends ExceptionBreakpoint { public void createRequest(DebugProcessImpl debugProcess) { DebuggerManagerThreadImpl.assertIsManagerThread(); - if (!ENABLED || !debugProcess.isAttached() || debugProcess.areBreakpointsMuted() || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) { + if (!isEnabled() || !debugProcess.isAttached() || debugProcess.areBreakpointsMuted() || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) { return; } super.processClassPrepare(debugProcess, null); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpointFactory.java deleted file mode 100644 index f595c1d81c65..000000000000 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpointFactory.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.debugger.ui.breakpoints; - -import com.intellij.icons.AllIcons; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Key; -import org.jdom.Element; - -import javax.swing.*; - -/** - * @author Eugene Zhuravlev - * Date: Apr 26, 2005 - */ -public class AnyExceptionBreakpointFactory extends BreakpointFactory{ - public Breakpoint createBreakpoint(Project project, final Element element) { - return new AnyExceptionBreakpoint(project); - } - - public Icon getIcon() { - return AllIcons.Debugger.Db_exception_breakpoint; - } - - public Icon getDisabledIcon() { - return AllIcons.Debugger.Db_disabled_exception_breakpoint; - } - - @Override - protected String getHelpID() { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public String getDisplayName() { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public BreakpointPropertiesPanel createBreakpointPropertiesPanel(Project project, boolean compact) { - return new ExceptionBreakpointPropertiesPanel(project, compact); - } - - @Override - public boolean breakpointCanBeRemoved(Breakpoint breakpoint) { - return false; - } - - public Key<AnyExceptionBreakpoint> getBreakpointCategory() { - return AnyExceptionBreakpoint.ANY_EXCEPTION_BREAKPOINT; - } -} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java index 1b370ca47ded..bbbcf8ef1265 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java @@ -30,45 +30,62 @@ import com.intellij.debugger.engine.requests.RequestManagerImpl; import com.intellij.debugger.jdi.StackFrameProxyImpl; import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; import com.intellij.debugger.requests.ClassPrepareRequestor; +import com.intellij.debugger.settings.DebuggerSettings; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.JDOMExternalizerUtil; import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.WriteExternalException; import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; import com.intellij.ui.AppUIUtil; +import com.intellij.ui.classFilter.ClassFilter; import com.intellij.util.StringBuilderSpinAllocator; -import com.sun.jdi.ObjectReference; -import com.sun.jdi.ReferenceType; -import com.sun.jdi.Value; -import com.sun.jdi.VoidValue; +import com.intellij.xdebugger.breakpoints.SuspendPolicy; +import com.intellij.xdebugger.breakpoints.XBreakpoint; +import com.intellij.xdebugger.breakpoints.XLineBreakpoint; +import com.sun.jdi.*; import com.sun.jdi.event.LocatableEvent; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties; import javax.swing.*; import java.util.List; -public abstract class Breakpoint extends FilteredRequestor implements ClassPrepareRequestor { - public boolean ENABLED = true; - public boolean LOG_ENABLED = false; - public boolean LOG_EXPRESSION_ENABLED = false; - public boolean REMOVE_AFTER_HIT = false; - private TextWithImports myLogMessage; // an expression to be evaluated and printed +public abstract class Breakpoint<P extends JavaBreakpointProperties> implements FilteredRequestor, ClassPrepareRequestor { + final XBreakpoint<P> myXBreakpoint; + protected final Project myProject; + + //private boolean ENABLED = true; + //private boolean LOG_ENABLED = false; + //private boolean LOG_EXPRESSION_ENABLED = false; + //private boolean REMOVE_AFTER_HIT = false; + //private TextWithImports myLogMessage; // an expression to be evaluated and printed @NonNls private static final String LOG_MESSAGE_OPTION_NAME = "LOG_MESSAGE"; public static final Breakpoint[] EMPTY_ARRAY = new Breakpoint[0]; protected boolean myCachedVerifiedState = false; + //private TextWithImportsImpl myLogMessage; - protected Breakpoint(@NotNull Project project) { - super(project); - myLogMessage = new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, ""); + protected Breakpoint(@NotNull Project project, XBreakpoint<P> xBreakpoint) { + //super(project); + myProject = project; + myXBreakpoint = xBreakpoint; + //myLogMessage = new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, ""); //noinspection AbstractMethodCallInConstructor - final BreakpointDefaults defaults = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().getBreakpointDefaults(getCategory()); - SUSPEND_POLICY = defaults.getSuspendPolicy(); - CONDITION_ENABLED = defaults.isConditionEnabled(); + //final BreakpointDefaults defaults = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().getBreakpointDefaults(getCategory()); + //SUSPEND_POLICY = defaults.getSuspendPolicy(); + //CONDITION_ENABLED = defaults.isConditionEnabled(); + } + + public Project getProject() { + return myProject; + } + + protected P getProperties() { + return myXBreakpoint.getProperties(); } public abstract PsiClass getPsiClass(); @@ -100,6 +117,16 @@ public abstract class Breakpoint extends FilteredRequestor implements ClassPrepa myCachedVerifiedState = isVerified; } + public boolean isRemoveAfterHit() { + return myXBreakpoint instanceof XLineBreakpoint && ((XLineBreakpoint)myXBreakpoint).isTemporary(); + } + + public void setRemoveAfterHit(boolean value) { + if (myXBreakpoint instanceof XLineBreakpoint) { + ((XLineBreakpoint)myXBreakpoint).setTemporary(value); + } + } + @Nullable public String getShortClassName() { final String className = getClassName(); @@ -210,19 +237,19 @@ public abstract class Breakpoint extends FilteredRequestor implements ClassPrepa private void runAction(final EvaluationContextImpl context, LocatableEvent event) { final DebugProcessImpl debugProcess = context.getDebugProcess(); - if (LOG_ENABLED || LOG_EXPRESSION_ENABLED) { + if (isLogEnabled() || isLogExpressionEnabled()) { final StringBuilder buf = StringBuilderSpinAllocator.alloc(); try { - if (LOG_ENABLED) { + if (myXBreakpoint.isLogMessage()) { buf.append(getEventMessage(event)); buf.append("\n"); } - final TextWithImports expressionToEvaluate = getLogMessage(); - if (LOG_EXPRESSION_ENABLED && expressionToEvaluate != null && !"".equals(expressionToEvaluate.getText())) { + if (isLogExpressionEnabled()) { if(!debugProcess.isAttached()) { return; } - + + final TextWithImports expressionToEvaluate = getLogMessage(); try { ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(getProject(), new EvaluatingComputable<ExpressionEvaluator>() { @Override @@ -252,11 +279,112 @@ public abstract class Breakpoint extends FilteredRequestor implements ClassPrepa StringBuilderSpinAllocator.dispose(buf); } } - if (REMOVE_AFTER_HIT) { + if (isRemoveAfterHit()) { handleTemporaryBreakpointHit(debugProcess); } } + /** + * @return true if the ID was added or false otherwise + */ + private boolean hasObjectID(long id) { + for (InstanceFilter instanceFilter : getInstanceFilters()) { + if (instanceFilter.getId() == id) { + return true; + } + } + return false; + } + + public boolean evaluateCondition(final EvaluationContextImpl context, LocatableEvent event) throws EvaluateException { + if(isCountFilterEnabled()) { + final DebugProcessImpl debugProcess = context.getDebugProcess(); + debugProcess.getVirtualMachineProxy().suspend(); + debugProcess.getRequestsManager().deleteRequest(this); + ((Breakpoint)this).createRequest(debugProcess); + debugProcess.getVirtualMachineProxy().resume(); + } + if (isInstanceFiltersEnabled()) { + Value value = context.getThisObject(); + if (value != null) { // non-static + ObjectReference reference = (ObjectReference)value; + if(!hasObjectID(reference.uniqueID())) { + return false; + } + } + } + + if (isClassFiltersEnabled()) { + String typeName = calculateEventClass(context, event); + if (!typeMatchesClassFilters(typeName)) return false; + } + + if (isConditionEnabled() && !getCondition().getText().isEmpty()) { + try { + ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(context.getProject(), new EvaluatingComputable<ExpressionEvaluator>() { + public ExpressionEvaluator compute() throws EvaluateException { + final SourcePosition contextSourcePosition = ContextUtil.getSourcePosition(context); + // IMPORTANT: calculate context psi element basing on the location where the exception + // has been hit, not on the location where it was set. (For line breakpoints these locations are the same, however, + // for method, exception and field breakpoints these locations differ) + PsiElement contextPsiElement = ContextUtil.getContextElement(contextSourcePosition); + if (contextPsiElement == null) { + contextPsiElement = getEvaluationElement(); // as a last resort + } + return EvaluatorBuilderImpl.build(getCondition(), contextPsiElement, contextSourcePosition); + } + }); + final Value value = evaluator.evaluate(context); + if (!(value instanceof BooleanValue)) { + throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.boolean.expected")); + } + if(!((BooleanValue)value).booleanValue()) { + return false; + } + } + catch (EvaluateException ex) { + if(ex.getCause() instanceof VMDisconnectedException) { + return false; + } + throw EvaluateExceptionUtil.createEvaluateException( + DebuggerBundle.message("error.failed.evaluating.breakpoint.condition", getCondition(), ex.getMessage()) + ); + } + return true; + } + + return true; + } + + protected String calculateEventClass(EvaluationContextImpl context, LocatableEvent event) throws EvaluateException { + return event.location().declaringType().name(); + } + + private boolean typeMatchesClassFilters(@Nullable String typeName) { + if (typeName == null) { + return true; + } + boolean matches = false, hasEnabled = false; + for (ClassFilter classFilter : getClassFilters()) { + if (classFilter.isEnabled()) { + hasEnabled = true; + if (classFilter.matches(typeName)) { + matches = true; + break; + } + } + } + if(hasEnabled && !matches) { + return false; + } + for (ClassFilter classFilter : getClassExclusionFilters()) { + if (classFilter.isEnabled() && classFilter.matches(typeName)) { + return false; + } + } + return true; + } + private void handleTemporaryBreakpointHit(final DebugProcessImpl debugProcess) { debugProcess.addDebugProcessListener(new DebugProcessAdapter() { @Override @@ -288,26 +416,213 @@ public abstract class Breakpoint extends FilteredRequestor implements ClassPrepa RequestManagerImpl.deleteRequests(this); } - @Override public void readExternal(Element parentNode) throws InvalidDataException { - super.readExternal(parentNode); - String logMessage = JDOMExternalizerUtil.readField(parentNode, LOG_MESSAGE_OPTION_NAME); - if (logMessage != null) { - setLogMessage(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, logMessage)); + FilteredRequestorImpl requestor = new FilteredRequestorImpl(myProject); + requestor.readTo(parentNode, this); + try { + setEnabled(Boolean.valueOf(JDOMExternalizerUtil.readField(parentNode, "ENABLED"))); + } catch (Exception e) { } + try { + setLogEnabled(Boolean.valueOf(JDOMExternalizerUtil.readField(parentNode, "LOG_ENABLED"))); + } catch (Exception e) { + } + try { + if (Boolean.valueOf(JDOMExternalizerUtil.readField(parentNode, "LOG_EXPRESSION_ENABLED"))) { + String logMessage = JDOMExternalizerUtil.readField(parentNode, LOG_MESSAGE_OPTION_NAME); + if (logMessage != null) { + setLogMessage(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, logMessage)); + } + } + } catch (Exception e) { + } + try { + setRemoveAfterHit(Boolean.valueOf(JDOMExternalizerUtil.readField(parentNode, "REMOVE_AFTER_HIT"))); + } catch (Exception e) { + } + } + + //@Override + //public void writeExternal(Element parentNode) throws WriteExternalException { + //super.writeExternal(parentNode); + //JDOMExternalizerUtil.writeField(parentNode, LOG_MESSAGE_OPTION_NAME, getLogMessage().toExternalForm()); + //} + + //public void setLogMessage(TextWithImports logMessage) { + // myLogMessage = logMessage; + //} + + public abstract PsiElement getEvaluationElement(); + + protected TextWithImports getLogMessage() { + return new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, myXBreakpoint.getLogExpression()); + } + + protected TextWithImports getCondition() { + return new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, myXBreakpoint.getCondition()); + } + + public boolean isEnabled() { + return myXBreakpoint.isEnabled(); + } + + public void setEnabled(boolean enabled) { + myXBreakpoint.setEnabled(enabled); + } + + protected boolean isLogEnabled() { + return myXBreakpoint.isLogMessage(); + } + + public void setLogEnabled(boolean logEnabled) { + myXBreakpoint.setLogMessage(logEnabled); + } + + protected boolean isLogExpressionEnabled() { + String expression = myXBreakpoint.getLogExpression(); + if (expression == null || expression.isEmpty()) { + return false; + } + return !getLogMessage().isEmpty(); + } + + @Override + public boolean isCountFilterEnabled() { + if (getProperties() == null) { + return false; + } + return getProperties().COUNT_FILTER_ENABLED; + } + public void setCountFilterEnabled(boolean enabled) { + getProperties().COUNT_FILTER_ENABLED = enabled; + } + + @Override + public int getCountFilter() { + return getProperties().COUNT_FILTER; + } + + public void setCountFilter(int filter) { + getProperties().COUNT_FILTER = filter; + } + + @Override + public boolean isClassFiltersEnabled() { + if (getProperties() == null) { + return false; + } + return getProperties().CLASS_FILTERS_ENABLED; + } + + public void setClassFiltersEnabled(boolean enabled) { + getProperties().CLASS_FILTERS_ENABLED = enabled; + } + + @Override + public ClassFilter[] getClassFilters() { + return getProperties().getClassFilters(); + } + + public void setClassFilters(ClassFilter[] filters) { + getProperties().setClassFilters(filters); + } + + @Override + public ClassFilter[] getClassExclusionFilters() { + return getProperties().getClassExclusionFilters(); + } + + protected void setClassExclusionFilters(ClassFilter[] filters) { + getProperties().setClassExclusionFilters(filters); + } + + @Override + public boolean isInstanceFiltersEnabled() { + if (getProperties() == null) { + return false; + } + return getProperties().INSTANCE_FILTERS_ENABLED; + } + + public void setInstanceFiltersEnabled(boolean enabled) { + getProperties().INSTANCE_FILTERS_ENABLED = enabled; } @Override - public void writeExternal(Element parentNode) throws WriteExternalException { - super.writeExternal(parentNode); - JDOMExternalizerUtil.writeField(parentNode, LOG_MESSAGE_OPTION_NAME, getLogMessage().toExternalForm()); + public InstanceFilter[] getInstanceFilters() { + return getProperties().getInstanceFilters(); + } + + public void setInstanceFilters(InstanceFilter[] filters) { + getProperties().setInstanceFilters(filters); + } + + private static String getSuspendPolicy(XBreakpoint breakpoint) { + switch (breakpoint.getSuspendPolicy()) { + case ALL: + return DebuggerSettings.SUSPEND_ALL; + case THREAD: + return DebuggerSettings.SUSPEND_THREAD; + case NONE: + return DebuggerSettings.SUSPEND_NONE; + + default: + throw new IllegalArgumentException("unknown suspend policy"); + } + } + + static SuspendPolicy transformSuspendPolicy(String policy) { + if (DebuggerSettings.SUSPEND_ALL.equals(policy)) { + return SuspendPolicy.ALL; + } else if (DebuggerSettings.SUSPEND_THREAD.equals(policy)) { + return SuspendPolicy.THREAD; + } else if (DebuggerSettings.SUSPEND_NONE.equals(policy)) { + return SuspendPolicy.NONE; + } else { + throw new IllegalArgumentException("unknown suspend policy"); + } } - public TextWithImports getLogMessage() { - return myLogMessage; + protected boolean isSuspend() { + return myXBreakpoint.getSuspendPolicy() != SuspendPolicy.NONE; + } + + @Override + public String getSuspendPolicy() { + return getSuspendPolicy(myXBreakpoint); + } + + public void setSuspendPolicy(String policy) { + myXBreakpoint.setSuspendPolicy(transformSuspendPolicy(policy)); + } + + protected void setLogMessage(@Nullable TextWithImports logMessage) { + if (logMessage != null && !logMessage.getText().isEmpty()) { + myXBreakpoint.setLogExpression(logMessage.toExternalForm()); + } + else { + myXBreakpoint.setLogExpression(null); + } + } + + protected boolean isConditionEnabled() { + String condition = myXBreakpoint.getCondition(); + if (condition == null || condition.isEmpty()) { + return false; + } + return !getCondition().isEmpty(); + } + + public void setCondition(@Nullable TextWithImports condition) { + if (condition != null && !condition.getText().isEmpty()) { + myXBreakpoint.setCondition(condition.toExternalForm()); + } + else { + myXBreakpoint.setCondition(null); + } } - public void setLogMessage(TextWithImports logMessage) { - myLogMessage = logMessage; + protected void addInstanceFilter(long l) { + getProperties().addInstanceFilter(l); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointFactory.java deleted file mode 100644 index 67c32935849e..000000000000 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointFactory.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.debugger.ui.breakpoints; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.extensions.ExtensionPointName; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Key; -import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointItem; -import org.jdom.Element; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; - -/** - * Used to deexternalize breakpoints of certain category while reading saved configuration and for creating configuration UI - */ -public abstract class BreakpointFactory { - public static final ExtensionPointName<BreakpointFactory> EXTENSION_POINT_NAME = - ExtensionPointName.create("com.intellij.debugger.breakpointFactory"); - - public static BreakpointFactory[] getBreakpointFactories() { - return ApplicationManager.getApplication().getExtensions(EXTENSION_POINT_NAME); - } - - public abstract Breakpoint createBreakpoint(Project project, final Element element); - - public abstract Key<? extends Breakpoint> getBreakpointCategory(); - - public abstract Icon getIcon(); - - public abstract Icon getDisabledIcon(); - - @Nullable - public static BreakpointFactory getInstance(Key<? extends Breakpoint> category) { - final BreakpointFactory[] allFactories = getBreakpointFactories(); - for (final BreakpointFactory factory : allFactories) { - if (category.equals(factory.getBreakpointCategory())) { - return factory; - } - } - return null; - } - - protected abstract String getHelpID(); - - public abstract String getDisplayName(); - - @Nullable - public abstract BreakpointPropertiesPanel createBreakpointPropertiesPanel(Project project, boolean compact); - - @Nullable - public Breakpoint addBreakpoint(Project project) { - return null; - } - - public boolean canAddBreakpoints() { - return false; - } - - public boolean breakpointCanBeRemoved(Breakpoint breakpoint) { - return true; - } - - public BreakpointItem createBreakpointItem(final Breakpoint breakpoint) { - return new JavaBreakpointItem(this, breakpoint); - } -} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java index 1bcbf3e9954b..76c55c7b4ae9 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java @@ -20,14 +20,11 @@ */ package com.intellij.debugger.ui.breakpoints; -import com.intellij.codeInsight.folding.impl.actions.ExpandRegionAction; import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.DebuggerInvocationUtil; import com.intellij.debugger.SourcePosition; import com.intellij.debugger.engine.BreakpointStepMethodFilter; import com.intellij.debugger.engine.DebugProcessImpl; -import com.intellij.debugger.engine.evaluation.CodeFragmentKind; -import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; import com.intellij.debugger.engine.requests.RequestManagerImpl; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.impl.DebuggerContextListener; @@ -35,41 +32,31 @@ import com.intellij.debugger.impl.DebuggerManagerImpl; import com.intellij.debugger.impl.DebuggerSession; import com.intellij.debugger.ui.JavaDebuggerSupport; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.EditorFactory; -import com.intellij.openapi.editor.event.*; import com.intellij.openapi.editor.markup.GutterIconRenderer; -import com.intellij.openapi.editor.markup.MarkupEditorFilterFactory; import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.fileEditor.FileDocumentManager; -import com.intellij.openapi.fileEditor.FileEditor; -import com.intellij.openapi.fileEditor.FileEditorManager; -import com.intellij.openapi.fileEditor.TextEditor; -import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.util.*; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiField; import com.intellij.psi.PsiFile; import com.intellij.util.Alarm; import com.intellij.util.EventDispatcher; -import com.intellij.util.IJSwingUtilities; -import com.intellij.util.SystemProperties; -import com.intellij.util.containers.MultiMap; import com.intellij.xdebugger.XDebuggerManager; import com.intellij.xdebugger.XDebuggerUtil; -import com.intellij.xdebugger.breakpoints.XBreakpointType; +import com.intellij.xdebugger.breakpoints.*; import com.intellij.xdebugger.impl.DebuggerSupport; import com.intellij.xdebugger.impl.XDebugSessionImpl; -import com.sun.jdi.Field; +import com.intellij.xdebugger.impl.breakpoints.XBreakpointManagerImpl; +import com.intellij.xdebugger.impl.breakpoints.XDependentBreakpointManager; import com.sun.jdi.InternalException; -import com.sun.jdi.ObjectReference; import com.sun.jdi.ThreadReference; import com.sun.jdi.request.*; import gnu.trove.THashMap; @@ -78,11 +65,9 @@ import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.java.debugger.breakpoints.JavaBreakpointAdapter; -import org.jetbrains.java.debugger.breakpoints.JavaBreakpointType; +import org.jetbrains.java.debugger.breakpoints.properties.JavaExceptionBreakpointProperties; import javax.swing.*; -import java.awt.event.MouseEvent; import java.util.*; public class BreakpointManager { @@ -94,15 +79,13 @@ public class BreakpointManager { @NonNls private static final String DEFAULT_CONDITION_STATE_ATTRIBUTE_NAME = "default_condition_enabled"; @NonNls private static final String RULES_GROUP_NAME = "breakpoint_rules"; + private static final String CONVERTED_PARAM = "converted"; private final Project myProject; - private AnyExceptionBreakpoint myAnyExceptionBreakpoint; - private final List<Breakpoint> myBreakpoints = new ArrayList<Breakpoint>(); // breakpoints storage, access should be synchronized - private final List<EnableBreakpointRule> myBreakpointRules = new ArrayList<EnableBreakpointRule>(); // breakpoint rules + private final Map<XBreakpoint, Breakpoint> myBreakpoints = new HashMap<XBreakpoint, Breakpoint>(); // breakpoints storage, access should be synchronized @Nullable private List<Breakpoint> myBreakpointsListForIteration = null; // another list for breakpoints iteration, unsynchronized access ok - private final MultiMap<Document, BreakpointWithHighlighter> myDocumentBreakpoints = MultiMap.createSmartList(); private final Map<String, String> myUIProperties = new LinkedHashMap<String, String>(); - private final Map<Key<? extends Breakpoint>, BreakpointDefaults> myBreakpointDefaults = new LinkedHashMap<Key<? extends Breakpoint>, BreakpointDefaults>(); + //private final Map<Key<? extends Breakpoint>, BreakpointDefaults> myBreakpointDefaults = new LinkedHashMap<Key<? extends Breakpoint>, BreakpointDefaults>(); private final EventDispatcher<BreakpointManagerListener> myDispatcher = EventDispatcher.create(BreakpointManagerListener.class); @@ -155,212 +138,35 @@ public class BreakpointManager { } } }); - - if (!project.isDefault()) { - XDebuggerManager.getInstance(project).getBreakpointManager().addBreakpointListener( - XBreakpointType.EXTENSION_POINT_NAME.findExtension(JavaBreakpointType.class), new JavaBreakpointAdapter(project), project); - } } public void init() { - EditorEventMulticaster eventMulticaster = EditorFactory.getInstance().getEventMulticaster(); - eventMulticaster.addEditorMouseListener(new EditorMouseAdapter() { - @Nullable private EditorMouseEvent myMousePressedEvent; - - @Nullable - private Breakpoint toggleBreakpoint(final boolean mostSuitingBreakpoint, final int line, boolean temporary) { - final Editor editor = FileEditorManager.getInstance(myProject).getSelectedTextEditor(); - if (editor == null) { - return null; - } - final Document document = editor.getDocument(); - final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document); - if (!JavaBreakpointType.doCanPutAt(psiFile)) { - return null; - } - - if (SystemProperties.getBooleanProperty("java.debugger.xBreakpoint", false) && - XBreakpointType.EXTENSION_POINT_NAME.findExtension(JavaBreakpointType.class) - .canPutAt(psiFile.getVirtualFile(), line, myProject)) { - return null; - } - - PsiDocumentManager.getInstance(myProject).commitDocument(document); - - int offset = editor.getCaretModel().getOffset(); - int editorLine = editor.getDocument().getLineNumber(offset); - if (editorLine != line) { - if (line < 0 || line >= document.getLineCount()) { - return null; - } - offset = editor.getDocument().getLineStartOffset(line); - } - - ExpandRegionAction.expandRegionAtOffset(myProject, editor, offset); - - Breakpoint breakpoint = findBreakpoint(document, offset, null); - if (breakpoint == null) { - boolean isInsideCompiledClass = StdFileTypes.CLASS.equals(psiFile.getFileType()); - if (mostSuitingBreakpoint || isInsideCompiledClass) { - breakpoint = addFieldBreakpoint(document, offset); - if (breakpoint == null) { - breakpoint = addMethodBreakpoint(document, line); - } - if (breakpoint == null && !isInsideCompiledClass) { - breakpoint = addLineBreakpoint(document, line); - } - } - else { - breakpoint = addLineBreakpoint(document, line); - - if (breakpoint == null) { - breakpoint = addMethodBreakpoint(document, line); - } - } - - if (breakpoint != null) { - breakpoint.REMOVE_AFTER_HIT = temporary; - RequestManagerImpl.createRequests(breakpoint); - } - return breakpoint; - } - else { - removeBreakpoint(breakpoint); - return null; - } - } - - private boolean isFromMyProject(Editor editor) { - FileEditor[] allEditors = FileEditorManager.getInstance(myProject).getAllEditors(); - for (FileEditor ed : allEditors) { - if (!(ed instanceof TextEditor)) { - continue; - } - if (((TextEditor)ed).getEditor().equals(editor)) { - return true; - } - } - return false; - } - - //mousePressed + mouseReleased is a hack to keep selection in editor when shift is pressed + XBreakpointManager manager = XDebuggerManager.getInstance(myProject).getBreakpointManager(); + manager.addBreakpointListener(new XBreakpointListener() { @Override - public void mousePressed(@NotNull EditorMouseEvent e) { - if (MarkupEditorFilterFactory.createIsDiffFilter().avaliableIn(e.getEditor())) return; - - if (e.isConsumed()) return; - - if (e.getArea() == EditorMouseEventArea.LINE_MARKERS_AREA && e.getMouseEvent().isShiftDown()) { - myMousePressedEvent = e; - e.consume(); + public void breakpointAdded(@NotNull XBreakpoint xBreakpoint) { + if (isJavaType(xBreakpoint)) { + onBreakpointAdded(xBreakpoint); } } @Override - public void mouseReleased(@NotNull EditorMouseEvent e) { - if (myMousePressedEvent != null) { - mouseClicked(e); - } - myMousePressedEvent = null; + public void breakpointRemoved(@NotNull XBreakpoint xBreakpoint) { + onBreakpointRemoved(xBreakpoint); } @Override - public void mouseClicked(@NotNull final EditorMouseEvent e) { - if (MarkupEditorFilterFactory.createIsDiffFilter().avaliableIn(e.getEditor())) return; - - if (e.isConsumed()) return; - - if (e.getArea() == EditorMouseEventArea.LINE_MARKERS_AREA) { - PsiDocumentManager.getInstance(myProject).commitAndRunReadAction(new Runnable() { - @Override - public void run() { - final Editor editor = e.getEditor(); - if (!isFromMyProject(editor)) { - return; - } - final int line = editor.xyToLogicalPosition(e.getMouseEvent().getPoint()).line; - final Document document = editor.getDocument(); - if (line < 0 || line >= document.getLineCount()) { - return; - } - MouseEvent event = e.getMouseEvent(); - if (event.isPopupTrigger()) { - return; - } - if (event.getButton() != 1) { - return; - } - if (e.getMouseEvent().isControlDown() || e.getMouseEvent().isMetaDown()) { - return; - } - - VirtualFile file = FileDocumentManager.getInstance().getFile(document); - if (file != null && XDebuggerUtil.getInstance().canPutBreakpointAt(myProject, file, line)) { - return; - } - e.consume(); - - DebuggerInvocationUtil.invokeLater(myProject, new Runnable() { - @Override - public void run() { - final boolean suitingBreakpoint = e.getMouseEvent().isAltDown() && !e.getMouseEvent().isShiftDown(); - final boolean temporary = e.getMouseEvent().isAltDown() && e.getMouseEvent().isShiftDown(); - - final Breakpoint breakpoint = toggleBreakpoint(suitingBreakpoint, line, temporary); - - - if (!e.getMouseEvent().isAltDown() && e.getMouseEvent().isShiftDown() && breakpoint != null) { - breakpoint.LOG_EXPRESSION_ENABLED = true; - String selection = editor.getSelectionModel().getSelectedText(); - String text = selection != null ? selection : DebuggerBundle.message("breakpoint.log.message", - breakpoint.getDisplayName()); - breakpoint.setLogMessage(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, text)); - breakpoint.SUSPEND = false; - editBreakpoint(breakpoint, editor); - - - //DialogWrapper dialog = DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager() - // .createConfigurationDialog(breakpoint, BreakpointPropertiesPanel.CONTROL_LOG_MESSAGE); - //dialog.show(); - // - //if (!dialog.isOK()) { - // removeBreakpoint(breakpoint); - //} - } - } - }); - } - }); + public void breakpointChanged(@NotNull XBreakpoint xBreakpoint) { + Breakpoint breakpoint = myBreakpoints.get(xBreakpoint); + if (breakpoint != null) { + fireBreakpointChanged(breakpoint); } } - }, myProject); - - eventMulticaster.addDocumentListener(new DocumentAdapter() { - private final Alarm myUpdateAlarm = new Alarm(); + }); + } - @Override - public void documentChanged(@NotNull final DocumentEvent e) { - final Document document = e.getDocument(); - //noinspection SynchronizeOnThis - synchronized (BreakpointManager.this) { - Collection<BreakpointWithHighlighter> breakpoints = myDocumentBreakpoints.get(document); - if (!breakpoints.isEmpty()) { - myUpdateAlarm.cancelAllRequests(); - // must create new array in order to avoid "concurrent modification" errors - final List<BreakpointWithHighlighter> breakpointsToUpdate = new ArrayList<BreakpointWithHighlighter>(breakpoints); - myUpdateAlarm.addRequest(new Runnable() { - @Override - public void run() { - if (!myProject.isDisposed()) { - PsiDocumentManager.getInstance(myProject).commitDocument(document); - update(breakpointsToUpdate); - } - } - }, 300, ModalityState.NON_MODAL); - } - } - } - }, myProject); + private XBreakpointManager getXBreakpointManager() { + return XDebuggerManager.getInstance(myProject).getBreakpointManager(); } public void editBreakpoint(final Breakpoint breakpoint, final Editor editor) { @@ -380,17 +186,34 @@ public class BreakpointManager { }); } - @NotNull - public BreakpointDefaults getBreakpointDefaults(Key<? extends Breakpoint> category) { - BreakpointDefaults defaults = myBreakpointDefaults.get(category); - if (defaults == null) { - defaults = new BreakpointDefaults(); - } - return defaults; - } + //@NotNull + //public BreakpointDefaults getBreakpointDefaults(Key<? extends Breakpoint> category) { + // BreakpointDefaults defaults = myBreakpointDefaults.get(category); + // if (defaults == null) { + // defaults = new BreakpointDefaults(); + // } + // return defaults; + //} public void setBreakpointDefaults(Key<? extends Breakpoint> category, BreakpointDefaults defaults) { - myBreakpointDefaults.put(category, defaults); + Class typeCls = null; + if (LineBreakpoint.CATEGORY.toString().equals(category.toString())) { + typeCls = JavaLineBreakpointType.class; + } + else if (MethodBreakpoint.CATEGORY.toString().equals(category.toString())) { + typeCls = JavaMethodBreakpointType.class; + } + else if (FieldBreakpoint.CATEGORY.toString().equals(category.toString())) { + typeCls = JavaFieldBreakpointType.class; + } + else if (ExceptionBreakpoint.CATEGORY.toString().equals(category.toString())) { + typeCls = JavaExceptionBreakpointType.class; + } + if (typeCls != null) { + XBreakpointType<XBreakpoint<?>, ?> type = XDebuggerUtil.getInstance().findBreakpointType(typeCls); + ((XBreakpointManagerImpl)getXBreakpointManager()).getBreakpointDefaults(type).setSuspendPolicy(Breakpoint.transformSuspendPolicy(defaults.getSuspendPolicy())); + } + //myBreakpointDefaults.put(category, defaults); } @@ -410,8 +233,8 @@ public class BreakpointManager { if (!LineBreakpoint.canAddLineBreakpoint(myProject, document, lineIndex)) { return null; } - - LineBreakpoint breakpoint = LineBreakpoint.create(myProject, document, lineIndex); + XLineBreakpoint xLineBreakpoint = addXLineBreakpoint(JavaLineBreakpointType.class, document, lineIndex); + LineBreakpoint breakpoint = LineBreakpoint.create(myProject, xLineBreakpoint); if (breakpoint == null) { return null; } @@ -420,15 +243,15 @@ public class BreakpointManager { return breakpoint; } - @Nullable - public FieldBreakpoint addFieldBreakpoint(Field field, ObjectReference object) { - ApplicationManager.getApplication().assertIsDispatchThread(); - final FieldBreakpoint fieldBreakpoint = FieldBreakpoint.create(myProject, field, object); - if (fieldBreakpoint != null) { - addBreakpoint(fieldBreakpoint); - } - return fieldBreakpoint; - } + //@Nullable + //public FieldBreakpoint addFieldBreakpoint(Field field, ObjectReference object) { + // ApplicationManager.getApplication().assertIsDispatchThread(); + // final FieldBreakpoint fieldBreakpoint = FieldBreakpoint.create(myProject, field, object, null); + // if (fieldBreakpoint != null) { + // addBreakpoint(fieldBreakpoint); + // } + // return fieldBreakpoint; + //} @Nullable public FieldBreakpoint addFieldBreakpoint(@NotNull Document document, int offset) { @@ -449,7 +272,8 @@ public class BreakpointManager { @Nullable public FieldBreakpoint addFieldBreakpoint(Document document, int lineIndex, String fieldName) { ApplicationManager.getApplication().assertIsDispatchThread(); - FieldBreakpoint fieldBreakpoint = FieldBreakpoint.create(myProject, document, lineIndex, fieldName); + XLineBreakpoint xBreakpoint = addXLineBreakpoint(JavaFieldBreakpointType.class, document, lineIndex); + FieldBreakpoint fieldBreakpoint = FieldBreakpoint.create(myProject, fieldName, xBreakpoint); if (fieldBreakpoint != null) { addBreakpoint(fieldBreakpoint); } @@ -457,21 +281,30 @@ public class BreakpointManager { } @NotNull - public ExceptionBreakpoint addExceptionBreakpoint(@NotNull String exceptionClassName, String packageName) { + public ExceptionBreakpoint addExceptionBreakpoint(@NotNull final String exceptionClassName, final String packageName) { ApplicationManager.getApplication().assertIsDispatchThread(); - ExceptionBreakpoint breakpoint = new ExceptionBreakpoint(myProject, exceptionClassName, packageName); - addBreakpoint(breakpoint); - if (LOG.isDebugEnabled()) { - LOG.debug("ExceptionBreakpoint Added"); - } - return breakpoint; + final JavaExceptionBreakpointType type = (JavaExceptionBreakpointType)XDebuggerUtil.getInstance().findBreakpointType(JavaExceptionBreakpointType.class); + return ApplicationManager.getApplication().runWriteAction(new Computable<ExceptionBreakpoint>() { + @Override + public ExceptionBreakpoint compute() { + XBreakpoint<JavaExceptionBreakpointProperties> xBreakpoint = XDebuggerManager.getInstance(myProject).getBreakpointManager() + .addBreakpoint(type, new JavaExceptionBreakpointProperties(exceptionClassName, packageName)); + ExceptionBreakpoint breakpoint = new ExceptionBreakpoint(myProject, exceptionClassName, packageName, xBreakpoint); + addBreakpoint(breakpoint); + if (LOG.isDebugEnabled()) { + LOG.debug("ExceptionBreakpoint Added"); + } + return breakpoint; + } + }); } @Nullable public MethodBreakpoint addMethodBreakpoint(Document document, int lineIndex) { ApplicationManager.getApplication().assertIsDispatchThread(); - MethodBreakpoint breakpoint = MethodBreakpoint.create(myProject, document, lineIndex); + XLineBreakpoint xBreakpoint = addXLineBreakpoint(JavaMethodBreakpointType.class, document, lineIndex); + MethodBreakpoint breakpoint = MethodBreakpoint.create(myProject, xBreakpoint); if (breakpoint == null) { return null; } @@ -482,10 +315,23 @@ public class BreakpointManager { return breakpoint; } + private <B extends XBreakpoint<?>> XLineBreakpoint addXLineBreakpoint(Class<? extends XBreakpointType<B,?>> typeCls, Document document, final int lineIndex) { + final XBreakpointType<B, ?> type = XDebuggerUtil.getInstance().findBreakpointType(typeCls); + final VirtualFile file = FileDocumentManager.getInstance().getFile(document); + return ApplicationManager.getApplication().runWriteAction(new Computable<XLineBreakpoint>() { + @Override + public XLineBreakpoint compute() { + return XDebuggerManager.getInstance(myProject).getBreakpointManager() + .addLineBreakpoint((XLineBreakpointType)type, file.getUrl(), lineIndex, + ((XLineBreakpointType)type).createBreakpointProperties(file, lineIndex)); + } + }); + } + @Nullable public WildcardMethodBreakpoint addMethodBreakpoint(String classPattern, String methodName) { ApplicationManager.getApplication().assertIsDispatchThread(); - WildcardMethodBreakpoint breakpoint = WildcardMethodBreakpoint.create(myProject, classPattern, methodName); + WildcardMethodBreakpoint breakpoint = WildcardMethodBreakpoint.create(myProject, classPattern, methodName, null); if (breakpoint == null) { return null; } @@ -531,14 +377,6 @@ public class BreakpointManager { */ @Nullable public <T extends BreakpointWithHighlighter> T findBreakpoint(final Document document, final int offset, @Nullable final Key<T> category) { - for (BreakpointWithHighlighter breakpointWithHighlighter : myDocumentBreakpoints.get(document)) { - if (breakpointWithHighlighter.isAt(document, offset) && - (category == null || category.equals(breakpointWithHighlighter.getCategory()))) { - //noinspection unchecked - return (T)breakpointWithHighlighter; - } - } - for (final Breakpoint breakpoint : getBreakpoints()) { if (breakpoint instanceof BreakpointWithHighlighter && ((BreakpointWithHighlighter)breakpoint).isAt(document, offset)) { if (category == null || category.equals(breakpoint.getCategory())) { @@ -550,7 +388,17 @@ public class BreakpointManager { return null; } + public Breakpoint findBreakpoint(XBreakpoint xBreakpoint) { + return myBreakpoints.get(xBreakpoint); + } + + private List<Element> myOriginalBreakpointsNodes = new ArrayList<Element>(); + public void readExternal(@NotNull final Element parentNode) { + // save old breakpoints + for (Element element : parentNode.getChildren()) { + myOriginalBreakpointsNodes.add(element.clone()); + } if (myProject.isOpen()) { doRead(parentNode); } @@ -577,6 +425,10 @@ public class BreakpointManager { if (group.getName().equals(RULES_GROUP_NAME)) { continue; } + // skip already converted + if (group.getAttribute(CONVERTED_PARAM) != null) { + continue; + } final String categoryName = group.getName(); final Key<Breakpoint> breakpointCategory = BreakpointCategory.lookup(categoryName); final String defaultPolicy = group.getAttributeValue(DEFAULT_SUSPEND_POLICY_ATTRIBUTE_NAME); @@ -586,16 +438,15 @@ public class BreakpointManager { if (!AnyExceptionBreakpoint.ANY_EXCEPTION_BREAKPOINT.equals(breakpointCategory)) { // for compatibility with previous format anyExceptionBreakpointGroup = group.getChild(AnyExceptionBreakpoint.ANY_EXCEPTION_BREAKPOINT.toString()); - final BreakpointFactory factory = BreakpointFactory.getInstance(breakpointCategory); - if (factory != null) { - for (final Object o : group.getChildren("breakpoint")) { - Element breakpointNode = (Element)o; - Breakpoint breakpoint = factory.createBreakpoint(myProject, breakpointNode); + //final BreakpointFactory factory = BreakpointFactory.getInstance(breakpointCategory); + //if (factory != null) { + for (Element breakpointNode : group.getChildren("breakpoint")) { + //Breakpoint breakpoint = factory.createBreakpoint(myProject, breakpointNode); + Breakpoint breakpoint = createBreakpoint(categoryName, breakpointNode); breakpoint.readExternal(breakpointNode); - addBreakpoint(breakpoint); nameToBreakpointMap.put(breakpoint.getDisplayName(), breakpoint); } - } + //} } else { anyExceptionBreakpointGroup = group; @@ -604,10 +455,14 @@ public class BreakpointManager { if (anyExceptionBreakpointGroup != null) { final Element breakpointElement = group.getChild("breakpoint"); if (breakpointElement != null) { - getAnyExceptionBreakpoint().readExternal(breakpointElement); + XBreakpointManager manager = XDebuggerManager.getInstance(myProject).getBreakpointManager(); + JavaExceptionBreakpointType type = (JavaExceptionBreakpointType)XDebuggerUtil.getInstance().findBreakpointType(JavaExceptionBreakpointType.class); + XBreakpoint<JavaExceptionBreakpointProperties> xBreakpoint = manager.getDefaultBreakpoint(type); + Breakpoint breakpoint = createJavaBreakpoint(xBreakpoint); + breakpoint.readExternal(breakpointElement); + addBreakpoint(breakpoint); } } - } } catch (InvalidDataException ignored) { @@ -615,9 +470,12 @@ public class BreakpointManager { final Element rulesGroup = parentNode.getChild(RULES_GROUP_NAME); if (rulesGroup != null) { - final List rules = rulesGroup.getChildren("rule"); - for (final Object rule1 : rules) { - final Element rule = (Element)rule1; + final List<Element> rules = rulesGroup.getChildren("rule"); + for (Element rule : rules) { + // skip already converted + if (rule.getAttribute(CONVERTED_PARAM) != null) { + continue; + } final Element master = rule.getChild(MASTER_BREAKPOINT_TAGNAME); if (master == null) { continue; @@ -634,7 +492,11 @@ public class BreakpointManager { if (slaveBreakpoint == null) { continue; } - addBreakpointRule(new EnableBreakpointRule(BreakpointManager.this, masterBreakpoint, slaveBreakpoint, "true".equalsIgnoreCase(rule.getAttributeValue("leaveEnabled")))); + + boolean leaveEnabled = "true".equalsIgnoreCase(rule.getAttributeValue("leaveEnabled")); + XDependentBreakpointManager dependentBreakpointManager = ((XBreakpointManagerImpl)getXBreakpointManager()).getDependentBreakpointManager(); + dependentBreakpointManager.setMasterBreakpoint(slaveBreakpoint.myXBreakpoint, masterBreakpoint.myXBreakpoint, leaveEnabled); + //addBreakpointRule(new EnableBreakpointRule(BreakpointManager.this, masterBreakpoint, slaveBreakpoint, leaveEnabled)); } } @@ -662,112 +524,190 @@ public class BreakpointManager { } } + private Breakpoint createBreakpoint(String category, Element breakpointNode) throws InvalidDataException { + XBreakpoint xBreakpoint = null; + if (category.equals(LineBreakpoint.CATEGORY.toString())) { + xBreakpoint = createXLineBreakpoint(JavaLineBreakpointType.class, breakpointNode); + } + else if (category.equals(MethodBreakpoint.CATEGORY.toString())) { + if (breakpointNode.getAttribute("url") != null) { + xBreakpoint = createXLineBreakpoint(JavaMethodBreakpointType.class, breakpointNode); + } + else { + xBreakpoint = createXBreakpoint(JavaWildcardMethodBreakpointType.class, breakpointNode); + } + } + else if (category.equals(FieldBreakpoint.CATEGORY.toString())) { + xBreakpoint = createXLineBreakpoint(JavaFieldBreakpointType.class, breakpointNode); + } + else if (category.equals(ExceptionBreakpoint.CATEGORY.toString())) { + xBreakpoint = createXBreakpoint(JavaExceptionBreakpointType.class, breakpointNode); + } + if (xBreakpoint == null) { + throw new IllegalStateException("Unknown breakpoint category " + category); + } + return myBreakpoints.get(xBreakpoint); + } + + private <B extends XBreakpoint<?>> XBreakpoint createXBreakpoint(Class<? extends XBreakpointType<B, ?>> typeCls, + Element breakpointNode) throws InvalidDataException { + final XBreakpointType<B, ?> type = XDebuggerUtil.getInstance().findBreakpointType(typeCls); + return ApplicationManager.getApplication().runWriteAction(new Computable<XBreakpoint>() { + @Override + public XBreakpoint compute() { + return XDebuggerManager.getInstance(myProject).getBreakpointManager() + .addBreakpoint((XBreakpointType)type, type.createProperties()); + }}); + } + + private <B extends XBreakpoint<?>> XLineBreakpoint createXLineBreakpoint(Class<? extends XBreakpointType<B, ?>> typeCls, + Element breakpointNode) throws InvalidDataException { + final String url = breakpointNode.getAttributeValue("url"); + VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(url); + if (vFile == null) { + throw new InvalidDataException(DebuggerBundle.message("error.breakpoint.file.not.found", url)); + } + final Document doc = FileDocumentManager.getInstance().getDocument(vFile); + if (doc == null) { + throw new InvalidDataException(DebuggerBundle.message("error.cannot.load.breakpoint.file", url)); + } + + final int line; + try { + //noinspection HardCodedStringLiteral + line = Integer.parseInt(breakpointNode.getAttributeValue("line")); + } + catch (Exception e) { + throw new InvalidDataException("Line number is invalid for breakpoint"); + } + return addXLineBreakpoint(typeCls, doc, line); + } + //used in Fabrique public synchronized void addBreakpoint(Breakpoint breakpoint) { - myBreakpoints.add(breakpoint); + myBreakpoints.put(breakpoint.myXBreakpoint, breakpoint); myBreakpointsListForIteration = null; - if (breakpoint instanceof BreakpointWithHighlighter) { - BreakpointWithHighlighter breakpointWithHighlighter = (BreakpointWithHighlighter)breakpoint; - final Document document = breakpointWithHighlighter.getDocument(); - if (document != null) { - myDocumentBreakpoints.putValue(document, breakpointWithHighlighter); - } - } + breakpoint.updateUI(); + RequestManagerImpl.createRequests(breakpoint); myDispatcher.getMulticaster().breakpointsChanged(); + if (breakpoint instanceof MethodBreakpoint || breakpoint instanceof WildcardMethodBreakpoint) { + XDebugSessionImpl.NOTIFICATION_GROUP.createNotification("Method breakpoints may dramatically slow down debugging", MessageType.WARNING).notify(myProject); + } } - public synchronized void removeBreakpoint(@Nullable final Breakpoint breakpoint) { - ApplicationManager.getApplication().assertIsDispatchThread(); + private synchronized void onBreakpointAdded(XBreakpoint xBreakpoint) { + Breakpoint breakpoint = createJavaBreakpoint(xBreakpoint); + addBreakpoint(breakpoint); + } + + public void removeBreakpoint(@Nullable final Breakpoint breakpoint) { if (breakpoint == null) { return; } + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + getXBreakpointManager().removeBreakpoint(breakpoint.myXBreakpoint); + } + }); + } + + private synchronized void onBreakpointRemoved(@Nullable final XBreakpoint xBreakpoint) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (xBreakpoint == null) { + return; + } - if (myBreakpoints.remove(breakpoint)) { - updateBreakpointRules(breakpoint); + Breakpoint breakpoint = myBreakpoints.remove(xBreakpoint); + if (breakpoint != null) { + //updateBreakpointRules(breakpoint); myBreakpointsListForIteration = null; - if (breakpoint instanceof BreakpointWithHighlighter) { - for (Document document : myDocumentBreakpoints.keySet()) { - if (myDocumentBreakpoints.remove(document, (BreakpointWithHighlighter)breakpoint)) { - break; - } - } - } //we delete breakpoints inside release, so gutter will not fire events to deleted breakpoints breakpoint.delete(); + RequestManagerImpl.deleteRequests(breakpoint); myDispatcher.getMulticaster().breakpointsChanged(); } } public void writeExternal(@NotNull final Element parentNode) { - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - removeInvalidBreakpoints(); - final Map<Key<? extends Breakpoint>, Element> categoryToElementMap = new THashMap<Key<? extends Breakpoint>, Element>(); - for (Key<? extends Breakpoint> category : myBreakpointDefaults.keySet()) { - final Element group = getCategoryGroupElement(categoryToElementMap, category, parentNode); - final BreakpointDefaults defaults = getBreakpointDefaults(category); - group.setAttribute(DEFAULT_SUSPEND_POLICY_ATTRIBUTE_NAME, String.valueOf(defaults.getSuspendPolicy())); - group.setAttribute(DEFAULT_CONDITION_STATE_ATTRIBUTE_NAME, String.valueOf(defaults.isConditionEnabled())); - } - // don't store invisible breakpoints - for (Breakpoint breakpoint : getBreakpoints()) { - if (breakpoint.isValid() && - (!(breakpoint instanceof BreakpointWithHighlighter) || ((BreakpointWithHighlighter)breakpoint).isVisible())) { - writeBreakpoint(getCategoryGroupElement(categoryToElementMap, breakpoint.getCategory(), parentNode), breakpoint); - } - } - final AnyExceptionBreakpoint anyExceptionBreakpoint = getAnyExceptionBreakpoint(); - final Element group = getCategoryGroupElement(categoryToElementMap, anyExceptionBreakpoint.getCategory(), parentNode); - writeBreakpoint(group, anyExceptionBreakpoint); - - final Element rules = new Element(RULES_GROUP_NAME); - parentNode.addContent(rules); - for (EnableBreakpointRule myBreakpointRule : myBreakpointRules) { - writeRule(myBreakpointRule, rules); - } + // restore old breakpoints + for (Element group : myOriginalBreakpointsNodes) { + if (group.getAttribute(CONVERTED_PARAM) == null) { + group.setAttribute(CONVERTED_PARAM, "true"); } - }); - - final Element uiProperties = new Element("ui_properties"); - parentNode.addContent(uiProperties); - for (final String name : myUIProperties.keySet()) { - Element property = new Element("property"); - uiProperties.addContent(property); - property.setAttribute("name", name); - property.setAttribute("value", myUIProperties.get(name)); - } - } - - @SuppressWarnings({"HardCodedStringLiteral"}) - private static void writeRule(@NotNull final EnableBreakpointRule enableBreakpointRule, @NotNull Element element) { - Element rule = new Element("rule"); - if (enableBreakpointRule.isLeaveEnabled()) { - rule.setAttribute("leaveEnabled", Boolean.toString(true)); + group.detach(); } - element.addContent(rule); - writeRuleBreakpoint(rule, MASTER_BREAKPOINT_TAGNAME, enableBreakpointRule.getMasterBreakpoint()); - writeRuleBreakpoint(rule, SLAVE_BREAKPOINT_TAGNAME, enableBreakpointRule.getSlaveBreakpoint()); - } - @SuppressWarnings({"HardCodedStringLiteral"}) private static void writeRuleBreakpoint(@NotNull final Element element, final String tagName, @NotNull final Breakpoint breakpoint) { - Element master = new Element(tagName); - element.addContent(master); - master.setAttribute("name", breakpoint.getDisplayName()); + parentNode.addContent(myOriginalBreakpointsNodes); + //ApplicationManager.getApplication().runReadAction(new Runnable() { + // @Override + // public void run() { + // removeInvalidBreakpoints(); + // final Map<Key<? extends Breakpoint>, Element> categoryToElementMap = new THashMap<Key<? extends Breakpoint>, Element>(); + // for (Key<? extends Breakpoint> category : myBreakpointDefaults.keySet()) { + // final Element group = getCategoryGroupElement(categoryToElementMap, category, parentNode); + // final BreakpointDefaults defaults = getBreakpointDefaults(category); + // group.setAttribute(DEFAULT_SUSPEND_POLICY_ATTRIBUTE_NAME, String.valueOf(defaults.getSuspendPolicy())); + // group.setAttribute(DEFAULT_CONDITION_STATE_ATTRIBUTE_NAME, String.valueOf(defaults.isConditionEnabled())); + // } + // // don't store invisible breakpoints + // for (Breakpoint breakpoint : getBreakpoints()) { + // if (breakpoint.isValid() && + // (!(breakpoint instanceof BreakpointWithHighlighter) || ((BreakpointWithHighlighter)breakpoint).isVisible())) { + // writeBreakpoint(getCategoryGroupElement(categoryToElementMap, breakpoint.getCategory(), parentNode), breakpoint); + // } + // } + // final AnyExceptionBreakpoint anyExceptionBreakpoint = getAnyExceptionBreakpoint(); + // final Element group = getCategoryGroupElement(categoryToElementMap, anyExceptionBreakpoint.getCategory(), parentNode); + // writeBreakpoint(group, anyExceptionBreakpoint); + // + // final Element rules = new Element(RULES_GROUP_NAME); + // parentNode.addContent(rules); + // //for (EnableBreakpointRule myBreakpointRule : myBreakpointRules) { + // // writeRule(myBreakpointRule, rules); + // //} + // } + //}); + // + //final Element uiProperties = new Element("ui_properties"); + //parentNode.addContent(uiProperties); + //for (final String name : myUIProperties.keySet()) { + // Element property = new Element("property"); + // uiProperties.addContent(property); + // property.setAttribute("name", name); + // property.setAttribute("value", myUIProperties.get(name)); + //} } - @SuppressWarnings({"HardCodedStringLiteral"}) - private static void writeBreakpoint(@NotNull final Element group, @NotNull final Breakpoint breakpoint) { - Element breakpointNode = new Element("breakpoint"); - group.addContent(breakpointNode); - try { - breakpoint.writeExternal(breakpointNode); - } - catch (WriteExternalException e) { - LOG.error(e); - } - } + //@SuppressWarnings({"HardCodedStringLiteral"}) + //private static void writeRule(@NotNull final EnableBreakpointRule enableBreakpointRule, @NotNull Element element) { + // Element rule = new Element("rule"); + // if (enableBreakpointRule.isLeaveEnabled()) { + // rule.setAttribute("leaveEnabled", Boolean.toString(true)); + // } + // element.addContent(rule); + // writeRuleBreakpoint(rule, MASTER_BREAKPOINT_TAGNAME, enableBreakpointRule.getMasterBreakpoint()); + // writeRuleBreakpoint(rule, SLAVE_BREAKPOINT_TAGNAME, enableBreakpointRule.getSlaveBreakpoint()); + //} + + //@SuppressWarnings({"HardCodedStringLiteral"}) private static void writeRuleBreakpoint(@NotNull final Element element, final String tagName, @NotNull final Breakpoint breakpoint) { + // Element master = new Element(tagName); + // element.addContent(master); + // master.setAttribute("name", breakpoint.getDisplayName()); + //} + + //@SuppressWarnings({"HardCodedStringLiteral"}) + //private static void writeBreakpoint(@NotNull final Element group, @NotNull final Breakpoint breakpoint) { + // Element breakpointNode = new Element("breakpoint"); + // group.addContent(breakpointNode); + // try { + // breakpoint.writeExternal(breakpointNode); + // } + // catch (WriteExternalException e) { + // LOG.error(e); + // } + //} private static <T extends Breakpoint> Element getCategoryGroupElement(@NotNull final Map<Key<? extends Breakpoint>, Element> categoryToElementMap, @NotNull final Key<T> category, @NotNull final Element parentNode) { Element group = categoryToElementMap.get(category); @@ -814,18 +754,37 @@ public class BreakpointManager { @NotNull public synchronized List<Breakpoint> getBreakpoints() { if (myBreakpointsListForIteration == null) { - myBreakpointsListForIteration = new ArrayList<Breakpoint>(myBreakpoints.size() + 1); - myBreakpointsListForIteration.addAll(myBreakpoints); - myBreakpointsListForIteration.add(getAnyExceptionBreakpoint()); + myBreakpointsListForIteration = new ArrayList<Breakpoint>(myBreakpoints.size()); + + XBreakpoint<?>[] xBreakpoints = ApplicationManager.getApplication().runReadAction(new Computable<XBreakpoint<?>[]>() { + public XBreakpoint<?>[] compute() { + return getXBreakpointManager().getAllBreakpoints(); + } + }); + for (XBreakpoint<?> xBreakpoint : xBreakpoints) { + if (isJavaType(xBreakpoint)) { + Breakpoint breakpoint = myBreakpoints.get(xBreakpoint); + if (breakpoint == null) { + breakpoint = createJavaBreakpoint(xBreakpoint); + myBreakpoints.put(xBreakpoint, breakpoint); + } + } + } + + myBreakpointsListForIteration.addAll(myBreakpoints.values()); } return myBreakpointsListForIteration; } - public AnyExceptionBreakpoint getAnyExceptionBreakpoint() { - if (myAnyExceptionBreakpoint == null) { - myAnyExceptionBreakpoint = new AnyExceptionBreakpoint(myProject); + private boolean isJavaType(XBreakpoint xBreakpoint) { + return xBreakpoint.getType() instanceof JavaBreakpointType; + } + + private Breakpoint createJavaBreakpoint(XBreakpoint xBreakpoint) { + if (xBreakpoint.getType() instanceof JavaBreakpointType) { + return ((JavaBreakpointType)xBreakpoint.getType()).createJavaBreakpoint(myProject, xBreakpoint); } - return myAnyExceptionBreakpoint; + throw new IllegalStateException("Unsupported breakpoint type:" + xBreakpoint.getType()); } //interaction with RequestManagerImpl @@ -963,6 +922,8 @@ public class BreakpointManager { private boolean myAllowMulticasting = true; private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); public void fireBreakpointChanged(Breakpoint breakpoint) { + breakpoint.reload(); + breakpoint.updateUI(); RequestManagerImpl.updateRequests(breakpoint); if (myAllowMulticasting) { // can be invoked from non-AWT thread @@ -988,84 +949,103 @@ public class BreakpointManager { } public void setBreakpointEnabled(@NotNull final Breakpoint breakpoint, final boolean enabled) { - if (breakpoint.ENABLED != enabled) { - breakpoint.ENABLED = enabled; - fireBreakpointChanged(breakpoint); - breakpoint.updateUI(); + if (breakpoint.isEnabled() != enabled) { + breakpoint.setEnabled(enabled); + //fireBreakpointChanged(breakpoint); + //breakpoint.updateUI(); } } public void addBreakpointRule(@NotNull EnableBreakpointRule rule) { - rule.init(); - myBreakpointRules.add(rule); + //rule.init(); + //myBreakpointRules.add(rule); } public boolean removeBreakpointRule(@NotNull EnableBreakpointRule rule) { - final boolean removed = myBreakpointRules.remove(rule); - if (removed) { - rule.dispose(); - } - return removed; + //final boolean removed = myBreakpointRules.remove(rule); + //if (removed) { + // rule.dispose(); + //} + //return removed; + return false; } public boolean removeBreakpointRule(@NotNull Breakpoint slaveBreakpoint) { - for (final EnableBreakpointRule rule : myBreakpointRules) { - if (slaveBreakpoint.equals(rule.getSlaveBreakpoint())) { - removeBreakpointRule(rule); - return true; - } - } + //for (final EnableBreakpointRule rule : myBreakpointRules) { + // if (slaveBreakpoint.equals(rule.getSlaveBreakpoint())) { + // removeBreakpointRule(rule); + // return true; + // } + //} return false; } - private void updateBreakpointRules(@NotNull Breakpoint removedBreakpoint) { - for (Iterator<EnableBreakpointRule> it = myBreakpointRules.iterator(); it.hasNext();) { - final EnableBreakpointRule rule = it.next(); - if (removedBreakpoint.equals(rule.getMasterBreakpoint()) || removedBreakpoint.equals(rule.getSlaveBreakpoint())) { - it.remove(); - } - } - } + //private void updateBreakpointRules(@NotNull Breakpoint removedBreakpoint) { + // for (Iterator<EnableBreakpointRule> it = myBreakpointRules.iterator(); it.hasNext();) { + // final EnableBreakpointRule rule = it.next(); + // if (removedBreakpoint.equals(rule.getMasterBreakpoint()) || removedBreakpoint.equals(rule.getSlaveBreakpoint())) { + // it.remove(); + // } + // } + //} + // copied from XDebugSessionImpl processDependencies public void processBreakpointHit(@NotNull final Breakpoint breakpoint) { - for (final EnableBreakpointRule rule : myBreakpointRules) { - rule.processBreakpointHit(breakpoint); + XDependentBreakpointManager dependentBreakpointManager = ((XBreakpointManagerImpl)getXBreakpointManager()).getDependentBreakpointManager(); + XBreakpoint xBreakpoint = breakpoint.myXBreakpoint; + if (!dependentBreakpointManager.isMasterOrSlave(xBreakpoint)) { + return; } - } - - public void setInitialBreakpointsState() { - myAllowMulticasting = false; - for (final EnableBreakpointRule myBreakpointRule : myBreakpointRules) { - myBreakpointRule.init(); + List<XBreakpoint<?>> breakpoints = dependentBreakpointManager.getSlaveBreakpoints(xBreakpoint); + for (final XBreakpoint<?> slaveBreakpoint : breakpoints) { + DebuggerInvocationUtil.invokeLater(myProject, new Runnable() { + @Override + public void run() { + slaveBreakpoint.setEnabled(true); + } + }); } - myAllowMulticasting = true; - if (!myBreakpointRules.isEmpty()) { - IJSwingUtilities.invoke(new Runnable() { + + if (dependentBreakpointManager.getMasterBreakpoint(xBreakpoint) != null && !dependentBreakpointManager.isLeaveEnabled(xBreakpoint)) { + DebuggerInvocationUtil.invokeLater(myProject, new Runnable() { @Override public void run() { - myDispatcher.getMulticaster().breakpointsChanged(); + breakpoint.setEnabled(false); } }); + //myDebuggerManager.getBreakpointManager().getLineBreakpointManager().queueBreakpointUpdate(breakpoint); } } + + public void setInitialBreakpointsState() { + //myAllowMulticasting = false; + //for (final EnableBreakpointRule myBreakpointRule : myBreakpointRules) { + // myBreakpointRule.init(); + //} + //myAllowMulticasting = true; + //if (!myBreakpointRules.isEmpty()) { + // IJSwingUtilities.invoke(new Runnable() { + // @Override + // public void run() { + // myDispatcher.getMulticaster().breakpointsChanged(); + // } + // }); + //} + } @Nullable public Breakpoint findMasterBreakpoint(@NotNull Breakpoint dependentBreakpoint) { - for (final EnableBreakpointRule rule : myBreakpointRules) { - if (dependentBreakpoint.equals(rule.getSlaveBreakpoint())) { - return rule.getMasterBreakpoint(); - } - } - return null; + XDependentBreakpointManager dependentBreakpointManager = ((XBreakpointManagerImpl)getXBreakpointManager()).getDependentBreakpointManager(); + return myBreakpoints.get(dependentBreakpointManager.getMasterBreakpoint(dependentBreakpoint.myXBreakpoint)); } @Nullable public EnableBreakpointRule findBreakpointRule(@NotNull Breakpoint dependentBreakpoint) { - for (final EnableBreakpointRule rule : myBreakpointRules) { - if (dependentBreakpoint.equals(rule.getSlaveBreakpoint())) { - return rule; - } - } + //for (final EnableBreakpointRule rule : myBreakpointRules) { + // if (dependentBreakpoint.equals(rule.getSlaveBreakpoint())) { + // return rule; + // } + //} return null; } @@ -1076,4 +1056,14 @@ public class BreakpointManager { public String setProperty(String name, String value) { return myUIProperties.put(name, value); } + + public static PsiFile getPsiFile(XBreakpoint xBreakpoint, Project project) { + try { + final Document document = FileDocumentManager.getInstance().getDocument(xBreakpoint.getSourcePosition().getFile()); + return PsiDocumentManager.getInstance(project).getPsiFile(document); + } catch (Exception e) { + LOG.error(e); + } + return null; + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java index d52044bbeb71..afeeb13aeb10 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java @@ -59,6 +59,9 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +/* + * Not used any more, since move to xBreakpoints + */ public abstract class BreakpointPropertiesPanel { private BreakpointChooser myMasterBreakpointChooser; @@ -208,8 +211,8 @@ public abstract class BreakpointPropertiesPanel { final ItemListener suspendPolicyChangeListener = new ItemListener() { @Override public void itemStateChanged(final ItemEvent e) { - final BreakpointDefaults defaults = getBreakpointManager(myProject).getBreakpointDefaults(breakpointCategory); - myMakeDefaultButton.setEnabled(!defaults.getSuspendPolicy().equals(getSelectedSuspendPolicy()) || defaults.isConditionEnabled() != myConditionCheckbox.isSelected()); + //final BreakpointDefaults defaults = getBreakpointManager(myProject).getBreakpointDefaults(breakpointCategory); + //myMakeDefaultButton.setEnabled(!defaults.getSuspendPolicy().equals(getSelectedSuspendPolicy()) || defaults.isConditionEnabled() != myConditionCheckbox.isSelected()); } }; @@ -426,13 +429,13 @@ public abstract class BreakpointPropertiesPanel { } private void updateSuspendPolicyRbFont() { - final String defPolicy = getBreakpointManager(myProject).getBreakpointDefaults(myBreakpointCategory).getSuspendPolicy(); + //final String defPolicy = getBreakpointManager(myProject).getBreakpointDefaults(myBreakpointCategory).getSuspendPolicy(); final Font font = myRbSuspendAll.getFont().deriveFont(Font.PLAIN); final Font boldFont = font.deriveFont(Font.BOLD); - myRbSuspendAll.setFont(DebuggerSettings.SUSPEND_ALL.equals(defPolicy)? boldFont : font); - myRbSuspendThread.setFont(DebuggerSettings.SUSPEND_THREAD.equals(defPolicy)? boldFont : font); + //myRbSuspendAll.setFont(DebuggerSettings.SUSPEND_ALL.equals(defPolicy)? boldFont : font); + //myRbSuspendThread.setFont(DebuggerSettings.SUSPEND_THREAD.equals(defPolicy)? boldFont : font); } protected ClassFilter createClassConditionFilter() { @@ -459,125 +462,126 @@ public abstract class BreakpointPropertiesPanel { * Init UI components with the values from Breakpoint */ public void initFrom(Breakpoint breakpoint, boolean moreOptionsVisible1) { - myBreakpoint = breakpoint; - boolean moreOptionsVisible = moreOptionsVisible1; - boolean actionsPanelVisible = moreOptionsVisible1; - - initMasterBreakpointPanel(); - - if (breakpoint.COUNT_FILTER > 0) { - myPassCountField.setText(Integer.toString(breakpoint.COUNT_FILTER)); - moreOptionsVisible = true; - } - else { - myPassCountField.setText(""); - } - - PsiElement context = breakpoint.getEvaluationElement(); - myPassCountCheckbox.setSelected(breakpoint.COUNT_FILTER_ENABLED); - - myConditionCheckbox.setSelected(breakpoint.CONDITION_ENABLED); - - myConditionCombo.setEnabled(breakpoint.CONDITION_ENABLED); - - myConditionCombo.setContext(context); - myConditionCombo.setText(breakpoint.getCondition() != null ? breakpoint.getCondition() : emptyText()); - - myCbSuspend.setSelected(breakpoint.SUSPEND); - myRbSuspendThread.setEnabled(myCbSuspend.isSelected()); - myRbSuspendAll.setEnabled(myCbSuspend.isSelected()); - - if(!breakpoint.SUSPEND) { - actionsPanelVisible = true; - } - if(DebuggerSettings.SUSPEND_THREAD.equals(breakpoint.SUSPEND_POLICY)){ - myRbSuspendThread.setSelected(true); - } - else { - myRbSuspendAll.setSelected(true); - } - - myCbSuspend.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent event) { - if (!myActionsPanel.isVisible()) { - if (!myCbSuspend.isSelected()) { - if (myDelegate != null) { - myDelegate.showActionsPanel(); - } - } - } - myRbSuspendThread.setEnabled(myCbSuspend.isSelected()); - myRbSuspendAll.setEnabled(myCbSuspend.isSelected()); - } - }); - myLogMessageCheckBox.setSelected(breakpoint.LOG_ENABLED); - myTemporaryCheckBox.setSelected(breakpoint.REMOVE_AFTER_HIT); - myEnabledCheckbox.setSelected(breakpoint.ENABLED); - myEnabledCheckbox.setText(breakpoint.getShortName() + " enabled"); - - DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().addBreakpointManagerListener(new BreakpointManagerListener() { - @Override - public void breakpointsChanged() { - myEnabledCheckbox.setSelected(myBreakpoint.ENABLED); - } - }); - - myEnabledCheckbox.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent event) { - if (myBreakpoint.ENABLED != myEnabledCheckbox.isSelected()) { - myBreakpoint.ENABLED = myEnabledCheckbox.isSelected(); - getBreakpointManager(myProject).fireBreakpointChanged(myBreakpoint); - myBreakpoint.updateUI(); - } - } - }); - myTemporaryCheckBox.setVisible(breakpoint instanceof LineBreakpoint); - myLogExpressionCheckBox.setSelected(breakpoint.LOG_EXPRESSION_ENABLED); - if (breakpoint.LOG_ENABLED || breakpoint.LOG_EXPRESSION_ENABLED || (breakpoint instanceof LineBreakpoint && breakpoint.REMOVE_AFTER_HIT)) { - actionsPanelVisible = true; - } - - myLogExpressionCombo.setContext(context); - - if (breakpoint.getLogMessage() != null) { - myLogExpressionCombo.setText(breakpoint.getLogMessage()); - } - else { - myLogExpressionCombo.setText(emptyText()); - } - - myLogExpressionCombo.setEnabled(breakpoint.LOG_EXPRESSION_ENABLED); - if (breakpoint.LOG_EXPRESSION_ENABLED) { - actionsPanelVisible = true; - } - - myInstanceFiltersCheckBox.setSelected(breakpoint.INSTANCE_FILTERS_ENABLED); - myInstanceFiltersField.setEnabled(breakpoint.INSTANCE_FILTERS_ENABLED); - myInstanceFiltersField.getTextField().setEditable(breakpoint.INSTANCE_FILTERS_ENABLED); - myInstanceFilters = breakpoint.getInstanceFilters(); - updateInstanceFilterEditor(true); - if (breakpoint.INSTANCE_FILTERS_ENABLED) { - moreOptionsVisible = true; - } - - myClassFiltersCheckBox.setSelected(breakpoint.CLASS_FILTERS_ENABLED); - myClassFiltersField.setEnabled(breakpoint.CLASS_FILTERS_ENABLED); - myClassFiltersField.getTextField().setEditable(breakpoint.CLASS_FILTERS_ENABLED); - myClassFilters = breakpoint.getClassFilters(); - myClassExclusionFilters = breakpoint.getClassExclusionFilters(); - updateClassFilterEditor(true); - if (breakpoint.CLASS_FILTERS_ENABLED) { - moreOptionsVisible = true; - } - - myBreakpointPsiClass = breakpoint.getPsiClass(); - - updateCheckboxes(); - - setActionsPanelVisible(actionsPanelVisible && !moreOptionsVisible1); - setMoreOptionsVisible(moreOptionsVisible); + //myBreakpoint = breakpoint; + //boolean moreOptionsVisible = moreOptionsVisible1; + //boolean actionsPanelVisible = moreOptionsVisible1; + // + //initMasterBreakpointPanel(); + // + //if (breakpoint.getCountFilter() > 0) { + // myPassCountField.setText(Integer.toString(breakpoint.getCountFilter())); + // moreOptionsVisible = true; + //} + //else { + // myPassCountField.setText(""); + //} + // + //PsiElement context = breakpoint.getEvaluationElement(); + //myPassCountCheckbox.setSelected(breakpoint.isCountFilterEnabled()); + // + //myConditionCheckbox.setSelected(breakpoint.isConditionEnabled()); + // + //myConditionCombo.setEnabled(breakpoint.isConditionEnabled()); + // + //myConditionCombo.setContext(context); + //myConditionCombo.setText(breakpoint.getCondition() != null ? breakpoint.getCondition() : emptyText()); + // + //myCbSuspend.setSelected(breakpoint.isSuspend()); + //myRbSuspendThread.setEnabled(myCbSuspend.isSelected()); + //myRbSuspendAll.setEnabled(myCbSuspend.isSelected()); + // + //if(!breakpoint.isSuspend()) { + // actionsPanelVisible = true; + //} + //if(DebuggerSettings.SUSPEND_THREAD.equals(breakpoint.getSuspendPolicy())){ + // myRbSuspendThread.setSelected(true); + //} + //else { + // myRbSuspendAll.setSelected(true); + //} + // + //myCbSuspend.addActionListener(new ActionListener() { + // @Override + // public void actionPerformed(ActionEvent event) { + // if (!myActionsPanel.isVisible()) { + // if (!myCbSuspend.isSelected()) { + // if (myDelegate != null) { + // myDelegate.showActionsPanel(); + // } + // } + // } + // myRbSuspendThread.setEnabled(myCbSuspend.isSelected()); + // myRbSuspendAll.setEnabled(myCbSuspend.isSelected()); + // } + //}); + //myLogMessageCheckBox.setSelected(breakpoint.isLogEnabled()); + //myTemporaryCheckBox.setSelected(breakpoint.isRemoveAfterHit()); + //myEnabledCheckbox.setSelected(breakpoint.isEnabled()); + //myEnabledCheckbox.setText(breakpoint.getShortName() + " enabled"); + // + //DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().addBreakpointManagerListener(new BreakpointManagerListener() { + // @Override + // public void breakpointsChanged() { + // myEnabledCheckbox.setSelected(myBreakpoint.isEnabled()); + // } + //}); + // + //myEnabledCheckbox.addActionListener(new ActionListener() { + // @Override + // public void actionPerformed(ActionEvent event) { + // if (myBreakpoint.isEnabled() != myEnabledCheckbox.isSelected()) { + // myBreakpoint.setEnabled(myEnabledCheckbox.isSelected()); + // getBreakpointManager(myProject).fireBreakpointChanged(myBreakpoint); + // myBreakpoint.updateUI(); + // } + // } + //}); + //myTemporaryCheckBox.setVisible(breakpoint instanceof LineBreakpoint); + //myLogExpressionCheckBox.setSelected(breakpoint.isLogExpressionEnabled()); + //if (breakpoint.isLogEnabled() || + // breakpoint.isLogExpressionEnabled() || (breakpoint instanceof LineBreakpoint && breakpoint.isRemoveAfterHit())) { + // actionsPanelVisible = true; + //} + // + //myLogExpressionCombo.setContext(context); + // + //if (breakpoint.getLogMessage() != null) { + // myLogExpressionCombo.setText(breakpoint.getLogMessage()); + //} + //else { + // myLogExpressionCombo.setText(emptyText()); + //} + // + //myLogExpressionCombo.setEnabled(breakpoint.isLogExpressionEnabled()); + //if (breakpoint.isLogExpressionEnabled()) { + // actionsPanelVisible = true; + //} + // + //myInstanceFiltersCheckBox.setSelected(breakpoint.isInstanceFiltersEnabled()); + //myInstanceFiltersField.setEnabled(breakpoint.isInstanceFiltersEnabled()); + //myInstanceFiltersField.getTextField().setEditable(breakpoint.isInstanceFiltersEnabled()); + //myInstanceFilters = breakpoint.getInstanceFilters(); + //updateInstanceFilterEditor(true); + //if (breakpoint.isInstanceFiltersEnabled()) { + // moreOptionsVisible = true; + //} + // + //myClassFiltersCheckBox.setSelected(breakpoint.isClassFiltersEnabled()); + //myClassFiltersField.setEnabled(breakpoint.isClassFiltersEnabled()); + //myClassFiltersField.getTextField().setEditable(breakpoint.isClassFiltersEnabled()); + //myClassFilters = breakpoint.getClassFilters(); + //myClassExclusionFilters = breakpoint.getClassExclusionFilters(); + //updateClassFilterEditor(true); + //if (breakpoint.isClassFiltersEnabled()) { + // moreOptionsVisible = true; + //} + // + //myBreakpointPsiClass = breakpoint.getPsiClass(); + // + //updateCheckboxes(); + // + //setActionsPanelVisible(actionsPanelVisible && !moreOptionsVisible1); + //setMoreOptionsVisible(moreOptionsVisible); } private void initMasterBreakpointPanel() { @@ -632,41 +636,41 @@ public abstract class BreakpointPropertiesPanel { */ public void saveTo(Breakpoint breakpoint) { - saveMasterBreakpoint(); - try { - String text = myPassCountField.getText().trim(); - breakpoint.COUNT_FILTER = !text.isEmpty() ? Integer.parseInt(text) : 0; - if (breakpoint.COUNT_FILTER < 0) { - breakpoint.COUNT_FILTER = 0; - } - } - catch (Exception ignored) { - } - - breakpoint.COUNT_FILTER_ENABLED = breakpoint.COUNT_FILTER > 0 && myPassCountCheckbox.isSelected(); - breakpoint.setCondition(myConditionCombo.getText()); - breakpoint.CONDITION_ENABLED = myConditionCheckbox.isSelected(); - breakpoint.setLogMessage(myLogExpressionCombo.getText()); - breakpoint.LOG_EXPRESSION_ENABLED = !breakpoint.getLogMessage().isEmpty() && myLogExpressionCheckBox.isSelected(); - breakpoint.LOG_ENABLED = myLogMessageCheckBox.isSelected(); - breakpoint.ENABLED = myEnabledCheckbox.isSelected(); - breakpoint.REMOVE_AFTER_HIT = myTemporaryCheckBox.isSelected(); - breakpoint.SUSPEND = myCbSuspend.isSelected(); - breakpoint.SUSPEND_POLICY = getSelectedSuspendPolicy(); - reloadInstanceFilters(); - reloadClassFilters(); - updateInstanceFilterEditor(true); - updateClassFilterEditor(true); - - breakpoint.INSTANCE_FILTERS_ENABLED = myInstanceFiltersField.getText().length() > 0 && myInstanceFiltersCheckBox.isSelected(); - breakpoint.CLASS_FILTERS_ENABLED = myClassFiltersField.getText().length() > 0 && myClassFiltersCheckBox.isSelected(); - breakpoint.setClassFilters(myClassFilters); - breakpoint.setClassExclusionFilters(myClassExclusionFilters); - breakpoint.setInstanceFilters(myInstanceFilters); - - myConditionCombo.addRecent(myConditionCombo.getText()); - myLogExpressionCombo.addRecent(myLogExpressionCombo.getText()); - breakpoint.updateUI(); + //saveMasterBreakpoint(); + //try { + // String text = myPassCountField.getText().trim(); + // breakpoint.setCountFilter(!text.isEmpty() ? Integer.parseInt(text) : 0); + // if (breakpoint.getCountFilter() < 0) { + // breakpoint.setCountFilter(0); + // } + //} + //catch (Exception ignored) { + //} + // + //breakpoint.setCountFilterEnabled(breakpoint.getCountFilter() > 0 && myPassCountCheckbox.isSelected()); + //breakpoint.setCondition(myConditionCombo.getText().getText()); + ////breakpoint.setConditionEnabled(myConditionCheckbox.isSelected()); + //breakpoint.setLogMessage(myLogExpressionCombo.getText()); + //breakpoint.setLogExpressionEnabled(!breakpoint.getLogMessage().isEmpty() && myLogExpressionCheckBox.isSelected()); + //breakpoint.setLogEnabled(myLogMessageCheckBox.isSelected()); + //breakpoint.setEnabled(myEnabledCheckbox.isSelected()); + //breakpoint.setRemoveAfterHit(myTemporaryCheckBox.isSelected()); + ////breakpoint.setSuspend(myCbSuspend.isSelected()); + //breakpoint.setSuspendPolicy(getSelectedSuspendPolicy()); + //reloadInstanceFilters(); + //reloadClassFilters(); + //updateInstanceFilterEditor(true); + //updateClassFilterEditor(true); + // + //breakpoint.setInstanceFiltersEnabled(myInstanceFiltersField.getText().length() > 0 && myInstanceFiltersCheckBox.isSelected()); + //breakpoint.setClassFiltersEnabled(myClassFiltersField.getText().length() > 0 && myClassFiltersCheckBox.isSelected()); + //breakpoint.setClassFilters(myClassFilters); + //breakpoint.setClassExclusionFilters(myClassExclusionFilters); + //breakpoint.setInstanceFilters(myInstanceFilters); + // + //myConditionCombo.addRecent(myConditionCombo.getText()); + //myLogExpressionCombo.addRecent(myLogExpressionCombo.getText()); + //breakpoint.updateUI(); } private static String concatWithEx(List<String> s, String concator, int N, String NthConcator) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java index 16b75279099e..8cd1bfbe8151 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java @@ -25,49 +25,49 @@ import com.intellij.debugger.engine.events.DebuggerCommandImpl; import com.intellij.debugger.engine.requests.RequestManagerImpl; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.settings.DebuggerSettings; -import com.intellij.debugger.ui.JavaDebuggerSupport; -import com.intellij.openapi.actionSystem.ActionGroup; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.ex.MarkupModelEx; import com.intellij.openapi.editor.impl.DocumentMarkupModel; -import com.intellij.openapi.editor.markup.*; +import com.intellij.openapi.editor.markup.MarkupEditorFilterFactory; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.*; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.psi.jsp.JspFile; -import com.intellij.ui.AppUIUtil; import com.intellij.ui.classFilter.ClassFilter; import com.intellij.util.StringBuilderSpinAllocator; -import com.intellij.xdebugger.impl.DebuggerSupport; -import com.intellij.xdebugger.impl.actions.EditBreakpointAction; +import com.intellij.xdebugger.XDebuggerManager; +import com.intellij.xdebugger.XSourcePosition; +import com.intellij.xdebugger.breakpoints.XBreakpoint; +import com.intellij.xdebugger.breakpoints.XBreakpointManager; +import com.intellij.xdebugger.breakpoints.XLineBreakpoint; import com.intellij.xdebugger.ui.DebuggerColors; import com.intellij.xml.util.XmlStringUtil; import com.sun.jdi.ReferenceType; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties; import javax.swing.*; -import java.awt.*; -import java.awt.dnd.DragSource; /** * User: lex * Date: Sep 2, 2003 * Time: 3:22:55 PM */ -public abstract class BreakpointWithHighlighter extends Breakpoint { +public abstract class BreakpointWithHighlighter<P extends JavaBreakpointProperties> extends Breakpoint<P> { @Nullable private RangeHighlighter myHighlighter; @@ -150,7 +150,7 @@ public abstract class BreakpointWithHighlighter extends Breakpoint { private Icon calcIcon(@Nullable DebugProcessImpl debugProcess) { final boolean muted = debugProcess != null && isMuted(debugProcess); - if (!ENABLED) { + if (!isEnabled()) { return getDisabledIcon(muted); } @@ -184,13 +184,14 @@ public abstract class BreakpointWithHighlighter extends Breakpoint { return getSetIcon(muted); } - protected BreakpointWithHighlighter(@NotNull Project project) { + protected BreakpointWithHighlighter(@NotNull Project project, XBreakpoint xBreakpoint) { //for persistency - super(project); + super(project, xBreakpoint); + reload(); } - public BreakpointWithHighlighter(@NotNull final Project project, @NotNull final RangeHighlighter highlighter) { - super(project); + public BreakpointWithHighlighter(@NotNull final Project project, @NotNull final RangeHighlighter highlighter, XBreakpoint breakpoint) { + super(project, breakpoint); myHighlighter = highlighter; setEditorFilter(highlighter); reload(); @@ -208,10 +209,10 @@ public abstract class BreakpointWithHighlighter extends Breakpoint { @Override public boolean isValid() { - return isPositionValid(getSourcePosition()); + return isPositionValid(myXBreakpoint.getSourcePosition()); } - private static boolean isPositionValid(@Nullable final SourcePosition sourcePosition) { + protected static boolean isPositionValid(@Nullable final XSourcePosition sourcePosition) { return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() { @Override public Boolean compute() { @@ -238,34 +239,34 @@ public abstract class BreakpointWithHighlighter extends Breakpoint { } buf.append(" <br> "); buf.append(DebuggerBundle.message("breakpoint.property.name.suspend.policy")).append(" : "); - if (DebuggerSettings.SUSPEND_NONE.equals(SUSPEND_POLICY) || !SUSPEND) { + if (DebuggerSettings.SUSPEND_NONE.equals(getSuspendPolicy()) || !isSuspend()) { buf.append(DebuggerBundle.message("breakpoint.properties.panel.option.suspend.none")); } - else if (DebuggerSettings.SUSPEND_ALL.equals(SUSPEND_POLICY)) { + else if (DebuggerSettings.SUSPEND_ALL.equals(getSuspendPolicy())) { buf.append(DebuggerBundle.message("breakpoint.properties.panel.option.suspend.all")); } - else if (DebuggerSettings.SUSPEND_THREAD.equals(SUSPEND_POLICY)) { + else if (DebuggerSettings.SUSPEND_THREAD.equals(getSuspendPolicy())) { buf.append(DebuggerBundle.message("breakpoint.properties.panel.option.suspend.thread")); } buf.append(" <br> "); buf.append(DebuggerBundle.message("breakpoint.property.name.log.message")).append(": "); - buf.append(LOG_ENABLED ? CommonBundle.getYesButtonText() : CommonBundle.getNoButtonText()); - if (LOG_EXPRESSION_ENABLED) { + buf.append(isLogEnabled() ? CommonBundle.getYesButtonText() : CommonBundle.getNoButtonText()); + if (isLogExpressionEnabled()) { buf.append(" <br> "); buf.append(DebuggerBundle.message("breakpoint.property.name.log.expression")).append(": "); buf.append(XmlStringUtil.escapeString(getLogMessage().getText())); } - if (CONDITION_ENABLED && getCondition() != null && getCondition().getText() != null && !getCondition().getText().isEmpty()) { + if (isConditionEnabled() && getCondition() != null && getCondition().getText() != null && !getCondition().getText().isEmpty()) { buf.append(" <br> "); buf.append(DebuggerBundle.message("breakpoint.property.name.condition")).append(": "); buf.append(XmlStringUtil.escapeString(getCondition().getText())); } - if (COUNT_FILTER_ENABLED) { + if (isCountFilterEnabled()) { buf.append(" <br> "); buf.append(DebuggerBundle.message("breakpoint.property.name.pass.count")).append(": "); - buf.append(COUNT_FILTER); + buf.append(getCountFilter()); } - if (CLASS_FILTERS_ENABLED) { + if (isClassFiltersEnabled()) { buf.append(" <br> "); buf.append(DebuggerBundle.message("breakpoint.property.name.class.filters")).append(": "); ClassFilter[] classFilters = getClassFilters(); @@ -273,7 +274,7 @@ public abstract class BreakpointWithHighlighter extends Breakpoint { buf.append(classFilter.getPattern()).append(" "); } } - if (INSTANCE_FILTERS_ENABLED) { + if (isInstanceFiltersEnabled()) { buf.append(" <br> "); buf.append(DebuggerBundle.message("breakpoint.property.name.instance.filters")); InstanceFilter[] instanceFilters = getInstanceFilters(); @@ -290,25 +291,23 @@ public abstract class BreakpointWithHighlighter extends Breakpoint { } @Override - public final void reload() { + public void reload() { ApplicationManager.getApplication().assertReadAccessAllowed(); - RangeHighlighter highlighter = myHighlighter; - if (highlighter != null && highlighter.isValid()) { - PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(highlighter.getDocument()); - if (psiFile != null) { - mySourcePosition = SourcePosition.createFromOffset(psiFile, highlighter.getStartOffset()); - reload(psiFile); - return; - } + final XSourcePosition position = myXBreakpoint.getSourcePosition(); + try { + final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(position.getFile()); + mySourcePosition = SourcePosition.createFromOffset(psiFile, position.getOffset()); + } catch (Exception e) { + mySourcePosition = null; } - mySourcePosition = null; + reload(BreakpointManager.getPsiFile(myXBreakpoint, myProject)); } @Override public void createRequest(@NotNull DebugProcessImpl debugProcess) { DebuggerManagerThreadImpl.assertIsManagerThread(); // check is this breakpoint is enabled, vm reference is valid and there're no requests created yet - if (!ENABLED || + if (!isEnabled() || !debugProcess.isAttached() || isMuted(debugProcess) || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) { @@ -329,7 +328,7 @@ public abstract class BreakpointWithHighlighter extends Breakpoint { @Override public void processClassPrepare(final DebugProcess debugProcess, final ReferenceType classType) { - if (!ENABLED || !isValid()) { + if (!isEnabled() || !isValid()) { return; } createRequestForPreparedClass((DebugProcessImpl)debugProcess, classType); @@ -383,20 +382,24 @@ public abstract class BreakpointWithHighlighter extends Breakpoint { private void updateGutter() { if (myVisible) { - RangeHighlighter highlighter = myHighlighter; - if (highlighter != null && highlighter.isValid() && isValid()) { - AppUIUtil.invokeLaterIfProjectAlive(myProject, new Runnable() { - @Override - public void run() { - if (isValid()) { - setupGutterRenderer(myHighlighter); - } - } - }); - } - else { - DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().removeBreakpoint(this); + if (isValid()) { + final XBreakpointManager breakpointManager = XDebuggerManager.getInstance(myProject).getBreakpointManager(); + breakpointManager.updateBreakpointPresentation((XLineBreakpoint)myXBreakpoint, getIcon(), null); } + //RangeHighlighter highlighter = myHighlighter; + //if (highlighter != null && highlighter.isValid() && isValid()) { + // AppUIUtil.invokeLaterIfProjectAlive(myProject, new Runnable() { + // @Override + // public void run() { + // if (isValid()) { + // setupGutterRenderer(myHighlighter); + // } + // } + // }); + //} + //else { + // DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().removeBreakpoint(this); + //} } } @@ -422,11 +425,10 @@ public abstract class BreakpointWithHighlighter extends Breakpoint { } public boolean isAt(@NotNull Document document, int offset) { - RangeHighlighter highlighter = getHighlighter(); - return highlighter != null && - highlighter.isValid() && - document.equals(highlighter.getDocument()) && - getSourcePosition().getLine() == document.getLineNumber(offset); + final VirtualFile file = FileDocumentManager.getInstance().getFile(document); + int line = document.getLineNumber(offset); + XSourcePosition position = myXBreakpoint.getSourcePosition(); + return position != null && position.getLine() == line && position.getFile().equals(file); } protected void reload(PsiFile psiFile) { @@ -448,9 +450,9 @@ public abstract class BreakpointWithHighlighter extends Breakpoint { }); } - private void setupGutterRenderer(@NotNull RangeHighlighter highlighter) { - highlighter.setGutterIconRenderer(new MyGutterIconRenderer(getIcon(), getDescription())); - } + //private void setupGutterRenderer(@NotNull RangeHighlighter highlighter) { + // highlighter.setGutterIconRenderer(new MyGutterIconRenderer(getIcon(), getDescription())); + //} @Override public abstract Key<? extends BreakpointWithHighlighter> getCategory(); @@ -559,7 +561,7 @@ public abstract class BreakpointWithHighlighter extends Breakpoint { public void readExternal(@NotNull Element breakpointNode) throws InvalidDataException { super.readExternal(breakpointNode); //noinspection HardCodedStringLiteral - final String url = breakpointNode.getAttributeValue("url"); + //final String url = breakpointNode.getAttributeValue("url"); //noinspection HardCodedStringLiteral final String className = breakpointNode.getAttributeValue("class"); @@ -573,146 +575,146 @@ public abstract class BreakpointWithHighlighter extends Breakpoint { myPackageName = packageName; } - VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(url); - if (vFile == null) { - throw new InvalidDataException(DebuggerBundle.message("error.breakpoint.file.not.found", url)); - } - final Document doc = FileDocumentManager.getInstance().getDocument(vFile); - if (doc == null) { - throw new InvalidDataException(DebuggerBundle.message("error.cannot.load.breakpoint.file", url)); - } - - // line number - final int line; - try { - //noinspection HardCodedStringLiteral - line = Integer.parseInt(breakpointNode.getAttributeValue("line")); - } - catch (Exception e) { - throw new InvalidDataException("Line number is invalid for breakpoint"); - } - if (line < 0) { - throw new InvalidDataException("Line number is invalid for breakpoint"); - } - - RangeHighlighter highlighter = createHighlighter(myProject, doc, line); - - if (highlighter == null) { - throw new InvalidDataException(""); - } - - myHighlighter = highlighter; - reload(); - } - - @Override - @SuppressWarnings({"HardCodedStringLiteral"}) - public void writeExternal(@NotNull Element parentNode) throws WriteExternalException { - super.writeExternal(parentNode); - PsiFile psiFile = getSourcePosition().getFile(); - final VirtualFile virtualFile = psiFile.getVirtualFile(); - final String url = virtualFile != null ? virtualFile.getUrl() : ""; - parentNode.setAttribute("url", url); - parentNode.setAttribute("line", Integer.toString(getSourcePosition().getLine())); - if (myClassName != null) { - parentNode.setAttribute("class", myClassName); - } - if (myPackageName != null) { - parentNode.setAttribute("package", myPackageName); - } - } - - private class MyGutterIconRenderer extends GutterIconRenderer { - private final Icon myIcon; - private final String myDescription; - - public MyGutterIconRenderer(@NotNull Icon icon, @NotNull String description) { - myIcon = icon; - myDescription = description; - } - - @Override - @NotNull - public Icon getIcon() { - return myIcon; - } - - @Override - public String getTooltipText() { - return myDescription; - } - - @Override - public Alignment getAlignment() { - return Alignment.RIGHT; - } - - @Override - public AnAction getClickAction() { - return new AnAction() { - @Override - public void actionPerformed(AnActionEvent e) { - DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().removeBreakpoint(BreakpointWithHighlighter.this); - } - }; - } - - @Override - public AnAction getMiddleButtonClickAction() { - return new AnAction() { - @Override - public void actionPerformed(AnActionEvent e) { - ENABLED = !ENABLED; - DebuggerManagerEx.getInstanceEx(getProject()).getBreakpointManager().fireBreakpointChanged(BreakpointWithHighlighter.this); - updateUI(); - } - }; - } - - @Override - public ActionGroup getPopupMenuActions() { - return null; - } - - @Nullable - @Override - public AnAction getRightButtonClickAction() { - return new EditBreakpointAction.ContextAction(this, BreakpointWithHighlighter.this, DebuggerSupport.getDebuggerSupport(JavaDebuggerSupport.class)); - } - - @Override - public GutterDraggableObject getDraggableObject() { - return new GutterDraggableObject() { - @Override - public boolean copy(int line, @NotNull VirtualFile file) { - final PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(file); - return psiFile != null && moveTo(SourcePosition.createFromLine(psiFile, line)); - } - - @Override - public Cursor getCursor(int line) { - final SourcePosition newPosition = SourcePosition.createFromLine(getSourcePosition().getFile(), line); - return canMoveTo(newPosition) ? DragSource.DefaultMoveDrop : DragSource.DefaultMoveNoDrop; - } - }; - } - - @Override - public boolean equals(@NotNull Object obj) { - return obj instanceof MyGutterIconRenderer && - Comparing.equal(getTooltipText(), ((MyGutterIconRenderer)obj).getTooltipText()) && - Comparing.equal(getIcon(), ((MyGutterIconRenderer)obj).getIcon()); - } - - @Override - public int hashCode() { - return getIcon().hashCode(); - } - - @Override - public String toString() { - return "LB " + getDisplayName(); - } - } + //VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(url); + //if (vFile == null) { + // throw new InvalidDataException(DebuggerBundle.message("error.breakpoint.file.not.found", url)); + //} + //final Document doc = FileDocumentManager.getInstance().getDocument(vFile); + //if (doc == null) { + // throw new InvalidDataException(DebuggerBundle.message("error.cannot.load.breakpoint.file", url)); + //} + // + //// line number + //final int line; + //try { + // //noinspection HardCodedStringLiteral + // line = Integer.parseInt(breakpointNode.getAttributeValue("line")); + //} + //catch (Exception e) { + // throw new InvalidDataException("Line number is invalid for breakpoint"); + //} + //if (line < 0) { + // throw new InvalidDataException("Line number is invalid for breakpoint"); + //} + // + //RangeHighlighter highlighter = createHighlighter(myProject, doc, line); + // + //if (highlighter == null) { + // throw new InvalidDataException(""); + //} + // + //myHighlighter = highlighter; + //reload(); + } + // + //@Override + //@SuppressWarnings({"HardCodedStringLiteral"}) + //public void writeExternal(@NotNull Element parentNode) throws WriteExternalException { + // super.writeExternal(parentNode); + // PsiFile psiFile = getSourcePosition().getFile(); + // final VirtualFile virtualFile = psiFile.getVirtualFile(); + // final String url = virtualFile != null ? virtualFile.getUrl() : ""; + // parentNode.setAttribute("url", url); + // parentNode.setAttribute("line", Integer.toString(getSourcePosition().getLine())); + // if (myClassName != null) { + // parentNode.setAttribute("class", myClassName); + // } + // if (myPackageName != null) { + // parentNode.setAttribute("package", myPackageName); + // } + //} + + //private class MyGutterIconRenderer extends GutterIconRenderer { + // private final Icon myIcon; + // private final String myDescription; + // + // public MyGutterIconRenderer(@NotNull Icon icon, @NotNull String description) { + // myIcon = icon; + // myDescription = description; + // } + // + // @Override + // @NotNull + // public Icon getIcon() { + // return myIcon; + // } + // + // @Override + // public String getTooltipText() { + // return myDescription; + // } + // + // @Override + // public Alignment getAlignment() { + // return Alignment.RIGHT; + // } + // + // @Override + // public AnAction getClickAction() { + // return new AnAction() { + // @Override + // public void actionPerformed(AnActionEvent e) { + // DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().removeBreakpoint(BreakpointWithHighlighter.this); + // } + // }; + // } + // + // @Override + // public AnAction getMiddleButtonClickAction() { + // return new AnAction() { + // @Override + // public void actionPerformed(AnActionEvent e) { + // setEnabled(!isEnabled()); + // DebuggerManagerEx.getInstanceEx(getProject()).getBreakpointManager().fireBreakpointChanged(BreakpointWithHighlighter.this); + // updateUI(); + // } + // }; + // } + // + // @Override + // public ActionGroup getPopupMenuActions() { + // return null; + // } + // + // @Nullable + // @Override + // public AnAction getRightButtonClickAction() { + // return new EditBreakpointAction.ContextAction(this, BreakpointWithHighlighter.this, DebuggerSupport.getDebuggerSupport(JavaDebuggerSupport.class)); + // } + // + // @Override + // public GutterDraggableObject getDraggableObject() { + // return new GutterDraggableObject() { + // @Override + // public boolean copy(int line, @NotNull VirtualFile file) { + // final PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(file); + // return psiFile != null && moveTo(SourcePosition.createFromLine(psiFile, line)); + // } + // + // @Override + // public Cursor getCursor(int line) { + // final SourcePosition newPosition = SourcePosition.createFromLine(getSourcePosition().getFile(), line); + // return canMoveTo(newPosition) ? DragSource.DefaultMoveDrop : DragSource.DefaultMoveNoDrop; + // } + // }; + // } + // + // @Override + // public boolean equals(@NotNull Object obj) { + // return obj instanceof MyGutterIconRenderer && + // Comparing.equal(getTooltipText(), ((MyGutterIconRenderer)obj).getTooltipText()) && + // Comparing.equal(getIcon(), ((MyGutterIconRenderer)obj).getIcon()); + // } + // + // @Override + // public int hashCode() { + // return getIcon().hashCode(); + // } + // + // @Override + // public String toString() { + // return "LB " + getDisplayName(); + // } + //} } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpoint.java index c6a19557f4e8..8a0b5159d5f7 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpoint.java @@ -34,13 +34,14 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizerUtil; import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.WriteExternalException; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.sun.jdi.AbsentInformationException; import com.sun.jdi.Location; import com.sun.jdi.ObjectReference; @@ -50,36 +51,32 @@ import com.sun.jdi.event.LocatableEvent; import com.sun.jdi.request.ExceptionRequest; import org.jdom.Element; import org.jetbrains.annotations.NonNls; +import org.jetbrains.java.debugger.breakpoints.properties.JavaExceptionBreakpointProperties; import javax.swing.*; -public class ExceptionBreakpoint extends Breakpoint { +public class ExceptionBreakpoint extends Breakpoint<JavaExceptionBreakpointProperties> { private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.ExceptionBreakpoint"); - public boolean NOTIFY_CAUGHT = true; - public boolean NOTIFY_UNCAUGHT = true; - private String myQualifiedName; - private String myPackageName; - protected final static String READ_NO_CLASS_NAME = DebuggerBundle.message("error.absent.exception.breakpoint.class.name"); public static final @NonNls Key<ExceptionBreakpoint> CATEGORY = BreakpointCategory.lookup("exception_breakpoints"); - public ExceptionBreakpoint(Project project) { - super(project); + public ExceptionBreakpoint(Project project, XBreakpoint xBreakpoint) { + super(project, xBreakpoint); } public Key<? extends ExceptionBreakpoint> getCategory() { return CATEGORY; } - protected ExceptionBreakpoint(Project project, String qualifiedName, String packageName) { - super(project); - myQualifiedName = qualifiedName; + protected ExceptionBreakpoint(Project project, String qualifiedName, String packageName, XBreakpoint xBreakpoint) { + super(project, xBreakpoint); + setQualifiedName(qualifiedName); if (packageName == null) { - myPackageName = calcPackageName(qualifiedName); + setPackageName(calcPackageName(qualifiedName)); } else { - myPackageName = packageName; + setPackageName(packageName); } } @@ -92,27 +89,27 @@ public class ExceptionBreakpoint extends Breakpoint { } public String getClassName() { - return myQualifiedName; + return getQualifiedName(); } public String getPackageName() { - return myPackageName; + return getProperties().myPackageName; } public PsiClass getPsiClass() { return PsiDocumentManager.getInstance(myProject).commitAndRunReadAction(new Computable<PsiClass>() { public PsiClass compute() { - return myQualifiedName != null ? DebuggerUtilsEx.findClass(myQualifiedName, myProject, GlobalSearchScope.allScope(myProject)) : null; + return getQualifiedName() != null ? DebuggerUtilsEx.findClass(getQualifiedName(), myProject, GlobalSearchScope.allScope(myProject)) : null; } }); } public String getDisplayName() { - return DebuggerBundle.message("breakpoint.exception.breakpoint.display.name", myQualifiedName); + return DebuggerBundle.message("breakpoint.exception.breakpoint.display.name", getQualifiedName()); } public Icon getIcon() { - if (!ENABLED) { + if (!isEnabled()) { final Breakpoint master = DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().findMasterBreakpoint(this); return master == null? AllIcons.Debugger.Db_disabled_exception_breakpoint : AllIcons.Debugger.Db_dep_exception_breakpoint; } @@ -124,20 +121,20 @@ public class ExceptionBreakpoint extends Breakpoint { public void createRequest(final DebugProcessImpl debugProcess) { DebuggerManagerThreadImpl.assertIsManagerThread(); - if (!ENABLED || !debugProcess.isAttached() || debugProcess.areBreakpointsMuted() || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) { + if (!isEnabled() || !debugProcess.isAttached() || debugProcess.areBreakpointsMuted() || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) { return; } SourcePosition classPosition = PsiDocumentManager.getInstance(myProject).commitAndRunReadAction(new Computable<SourcePosition>() { public SourcePosition compute() { - PsiClass psiClass = DebuggerUtilsEx.findClass(myQualifiedName, myProject, debugProcess.getSearchScope()); + PsiClass psiClass = DebuggerUtilsEx.findClass(getQualifiedName(), myProject, debugProcess.getSearchScope()); return psiClass != null ? SourcePosition.createFromElement(psiClass) : null; } }); if(classPosition == null) { - createOrWaitPrepare(debugProcess, myQualifiedName); + createOrWaitPrepare(debugProcess, getQualifiedName()); } else { createOrWaitPrepare(debugProcess, classPosition); @@ -146,11 +143,12 @@ public class ExceptionBreakpoint extends Breakpoint { public void processClassPrepare(DebugProcess process, ReferenceType refType) { DebugProcessImpl debugProcess = (DebugProcessImpl)process; - if (!ENABLED) { + if (!isEnabled()) { return; } // trying to create a request - ExceptionRequest request = debugProcess.getRequestsManager().createExceptionRequest(this, refType, NOTIFY_CAUGHT, NOTIFY_UNCAUGHT); + ExceptionRequest request = debugProcess.getRequestsManager().createExceptionRequest(this, refType, isNotifyCaught(), + isNotifyUncaught()); debugProcess.getRequestsManager().enableRequest(request); if (LOG.isDebugEnabled()) { if (refType != null) { @@ -170,7 +168,7 @@ public class ExceptionBreakpoint extends Breakpoint { } public String getEventMessage(LocatableEvent event) { - String exceptionName = (myQualifiedName != null)? myQualifiedName : "java.lang.Throwable"; + String exceptionName = (getQualifiedName() != null)? getQualifiedName() : "java.lang.Throwable"; String threadName = null; if (event instanceof ExceptionEvent) { ExceptionEvent exceptionEvent = (ExceptionEvent)event; @@ -216,15 +214,15 @@ public class ExceptionBreakpoint extends Breakpoint { return true; } - @SuppressWarnings({"HardCodedStringLiteral"}) public void writeExternal(Element parentNode) throws WriteExternalException { - super.writeExternal(parentNode); - if(myQualifiedName != null) { - parentNode.setAttribute("class_name", myQualifiedName); - } - if(myPackageName != null) { - parentNode.setAttribute("package_name", myPackageName); - } - } + //@SuppressWarnings({"HardCodedStringLiteral"}) public void writeExternal(Element parentNode) throws WriteExternalException { + // super.writeExternal(parentNode); + // if(getQualifiedName() != null) { + // parentNode.setAttribute("class_name", getQualifiedName()); + // } + // if(getPackageName() != null) { + // parentNode.setAttribute("package_name", getPackageName()); + // } + //} public PsiElement getEvaluationElement() { if (getClassName() == null) { @@ -235,16 +233,45 @@ public class ExceptionBreakpoint extends Breakpoint { public void readExternal(Element parentNode) throws InvalidDataException { super.readExternal(parentNode); + + //noinspection HardCodedStringLiteral + String packageName = parentNode.getAttributeValue("package_name"); + setPackageName(packageName != null? packageName : calcPackageName(packageName)); + + try { + getProperties().NOTIFY_CAUGHT = Boolean.valueOf(JDOMExternalizerUtil.readField(parentNode, "NOTIFY_CAUGHT")); + } catch (Exception e) { + } + try { + getProperties().NOTIFY_UNCAUGHT = Boolean.valueOf(JDOMExternalizerUtil.readField(parentNode, "NOTIFY_UNCAUGHT")); + } catch (Exception e) { + } + //noinspection HardCodedStringLiteral String className = parentNode.getAttributeValue("class_name"); - myQualifiedName = className; + setQualifiedName(className); if(className == null) { throw new InvalidDataException(READ_NO_CLASS_NAME); } + } - //noinspection HardCodedStringLiteral - String packageName = parentNode.getAttributeValue("package_name"); - myPackageName = packageName != null? packageName : calcPackageName(packageName); + private boolean isNotifyCaught() { + return getProperties().NOTIFY_CAUGHT; + } + + private boolean isNotifyUncaught() { + return getProperties().NOTIFY_UNCAUGHT; } + private String getQualifiedName() { + return getProperties().myQualifiedName; + } + + private void setQualifiedName(String qualifiedName) { + getProperties().myQualifiedName = qualifiedName; + } + + private void setPackageName(String packageName) { + getProperties().myPackageName = packageName; + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointFactory.java deleted file mode 100644 index 40b75c4ffc71..000000000000 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointFactory.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.debugger.ui.breakpoints; - -import com.intellij.debugger.DebuggerBundle; -import com.intellij.debugger.DebuggerManagerEx; -import com.intellij.debugger.HelpID; -import com.intellij.debugger.engine.JVMNameUtil; -import com.intellij.icons.AllIcons; -import com.intellij.ide.util.TreeClassChooser; -import com.intellij.ide.util.TreeClassChooserFactory; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Key; -import com.intellij.psi.JavaPsiFacade; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiClassOwner; -import com.intellij.psi.search.GlobalSearchScope; -import org.jdom.Element; - -import javax.swing.*; - -/** - * @author Eugene Zhuravlev - * Date: Apr 26, 2005 - */ -public class ExceptionBreakpointFactory extends BreakpointFactory { - public Breakpoint createBreakpoint(Project project, final Element element) { - return new ExceptionBreakpoint(project); - } - - public Icon getIcon() { - return AllIcons.Debugger.Db_exception_breakpoint; - } - - public Icon getDisabledIcon() { - return AllIcons.Debugger.Db_disabled_exception_breakpoint; - } - - @Override - protected String getHelpID() { - return HelpID.EXCEPTION_BREAKPOINTS; - } - - @Override - public String getDisplayName() { - return DebuggerBundle.message("exception.breakpoints.tab.title"); - } - - @Override - public BreakpointPropertiesPanel createBreakpointPropertiesPanel(Project project, boolean compact) { - return new ExceptionBreakpointPropertiesPanel(project, compact); - } - - public Key<ExceptionBreakpoint> getBreakpointCategory() { - return ExceptionBreakpoint.CATEGORY; - } - - @Override - public boolean canAddBreakpoints() { - return true; - } - - @Override - public Breakpoint addBreakpoint(Project project) { - ExceptionBreakpoint breakpoint = null; - final PsiClass throwableClass = - JavaPsiFacade.getInstance(project).findClass("java.lang.Throwable", GlobalSearchScope.allScope(project)); - TreeClassChooser chooser = TreeClassChooserFactory.getInstance(project) - .createInheritanceClassChooser(DebuggerBundle.message("add.exception.breakpoint.classchooser.title"), - GlobalSearchScope.allScope(project), throwableClass, true, true, null); - chooser.showDialog(); - PsiClass selectedClass = chooser.getSelected(); - String qName = selectedClass == null ? null : JVMNameUtil.getNonAnonymousClassName(selectedClass); - - if (qName != null && qName.length() > 0) { - breakpoint = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager() - .addExceptionBreakpoint(qName, ((PsiClassOwner)selectedClass.getContainingFile()).getPackageName()); - } - return breakpoint; - } -} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java index 6d02499f227c..4af7275d1258 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java @@ -21,31 +21,34 @@ package com.intellij.debugger.ui.breakpoints; import com.intellij.debugger.DebuggerBundle; -import com.intellij.ide.util.ClassFilter; -import com.intellij.openapi.project.Project; import com.intellij.ui.IdeBorderFactory; import com.intellij.util.ui.DialogUtil; +import com.intellij.xdebugger.breakpoints.XBreakpoint; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.java.debugger.breakpoints.properties.JavaExceptionBreakpointProperties; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -public class ExceptionBreakpointPropertiesPanel extends BreakpointPropertiesPanel { +public class ExceptionBreakpointPropertiesPanel extends XBreakpointCustomPropertiesPanel<XBreakpoint<JavaExceptionBreakpointProperties>> { private JCheckBox myNotifyCaughtCheckBox; private JCheckBox myNotifyUncaughtCheckBox; - private ExceptionBreakpoint myExceptionBreakpoint; + //private ExceptionBreakpoint myExceptionBreakpoint; - public ExceptionBreakpointPropertiesPanel(Project project, boolean compact) { - super(project, ExceptionBreakpoint.CATEGORY, compact); - } - - protected ClassFilter createClassConditionFilter() { - return null; - } + //public ExceptionBreakpointPropertiesPanel(Project project, boolean compact) { + // super(project, ExceptionBreakpoint.CATEGORY, compact); + //} - protected JComponent createSpecialBox() { + //protected ClassFilter createClassConditionFilter() { + // return null; + //} + @NotNull + @Override + public JComponent getComponent() { myNotifyCaughtCheckBox = new JCheckBox(DebuggerBundle.message("label.exception.breakpoint.properties.panel.caught.exception")); myNotifyUncaughtCheckBox = new JCheckBox(DebuggerBundle.message("label.exception.breakpoint.properties.panel.uncaught.exception")); DialogUtil.registerMnemonic(myNotifyCaughtCheckBox); @@ -91,25 +94,20 @@ public class ExceptionBreakpointPropertiesPanel extends BreakpointPropertiesPane return _panel; } - protected void updateCheckboxes() { - super.updateCheckboxes(); - myPassCountCheckbox.setEnabled(!(myExceptionBreakpoint instanceof AnyExceptionBreakpoint)); - } - - public void initFrom(Breakpoint breakpoint, boolean moreOptionsVisible) { - ExceptionBreakpoint exceptionBreakpoint = (ExceptionBreakpoint)breakpoint; - myExceptionBreakpoint = exceptionBreakpoint; - super.initFrom(breakpoint, moreOptionsVisible); + //protected void updateCheckboxes() { + // super.updateCheckboxes(); + // myPassCountCheckbox.setEnabled(!(myExceptionBreakpoint instanceof AnyExceptionBreakpoint)); + //} - myNotifyCaughtCheckBox.setSelected(exceptionBreakpoint.NOTIFY_CAUGHT); - myNotifyUncaughtCheckBox.setSelected(exceptionBreakpoint.NOTIFY_UNCAUGHT); + @Override + public void loadFrom(@NotNull XBreakpoint<JavaExceptionBreakpointProperties> breakpoint) { + myNotifyCaughtCheckBox.setSelected(breakpoint.getProperties().NOTIFY_CAUGHT); + myNotifyUncaughtCheckBox.setSelected(breakpoint.getProperties().NOTIFY_UNCAUGHT); } - public void saveTo(Breakpoint breakpoint) { - ExceptionBreakpoint exceptionBreakpoint = (ExceptionBreakpoint)breakpoint; - exceptionBreakpoint.NOTIFY_CAUGHT = myNotifyCaughtCheckBox.isSelected(); - exceptionBreakpoint.NOTIFY_UNCAUGHT = myNotifyUncaughtCheckBox.isSelected(); - - super.saveTo(breakpoint); + @Override + public void saveTo(@NotNull XBreakpoint<JavaExceptionBreakpointProperties> breakpoint) { + breakpoint.getProperties().NOTIFY_CAUGHT = myNotifyCaughtCheckBox.isSelected(); + breakpoint.getProperties().NOTIFY_UNCAUGHT = myNotifyUncaughtCheckBox.isSelected(); } }
\ No newline at end of file diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpoint.java index 365ae242b36d..aa3a29511a2f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpoint.java @@ -33,19 +33,17 @@ import com.intellij.icons.AllIcons; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizerUtil; import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.WriteExternalException; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Processor; import com.intellij.util.text.CharArrayUtil; import com.intellij.xdebugger.XDebuggerUtil; +import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.sun.jdi.*; import com.sun.jdi.event.AccessWatchpointEvent; import com.sun.jdi.event.LocatableEvent; @@ -55,26 +53,23 @@ import com.sun.jdi.request.ModificationWatchpointRequest; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.java.debugger.breakpoints.properties.JavaFieldBreakpointProperties; import javax.swing.*; -import java.util.List; -public class FieldBreakpoint extends BreakpointWithHighlighter { +public class FieldBreakpoint extends BreakpointWithHighlighter<JavaFieldBreakpointProperties> { private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.FieldBreakpoint"); - public boolean WATCH_MODIFICATION = true; - public boolean WATCH_ACCESS = false; private boolean myIsStatic; - private String myFieldName; @NonNls public static final Key<FieldBreakpoint> CATEGORY = BreakpointCategory.lookup("field_breakpoints"); - protected FieldBreakpoint(Project project) { - super(project); + protected FieldBreakpoint(Project project, XBreakpoint breakpoint) { + super(project, breakpoint); } - private FieldBreakpoint(Project project, RangeHighlighter highlighter, @NotNull String fieldName) { - super(project, highlighter); - myFieldName = fieldName; + private FieldBreakpoint(Project project, @NotNull String fieldName, XBreakpoint breakpoint) { + super(project, breakpoint); + setFieldName(fieldName); } public boolean isStatic() { @@ -82,10 +77,9 @@ public class FieldBreakpoint extends BreakpointWithHighlighter { } public String getFieldName() { - return myFieldName; + return getProperties().myFieldName; } - @Override protected Icon getDisabledIcon(boolean isMuted) { final Breakpoint master = DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().findMasterBreakpoint(this); @@ -128,7 +122,7 @@ public class FieldBreakpoint extends BreakpointWithHighlighter { @Override public PsiField compute() { final PsiClass psiClass = getPsiClassAt(sourcePosition); - return psiClass != null ? psiClass.findFieldByName(myFieldName, true) : null; + return psiClass != null ? psiClass.findFieldByName(getFieldName(), true) : null; } }); if (field != null) { @@ -142,11 +136,15 @@ public class FieldBreakpoint extends BreakpointWithHighlighter { super.reload(psiFile); PsiField field = PositionUtil.getPsiElementAt(getProject(), PsiField.class, getSourcePosition()); if(field != null) { - myFieldName = field.getName(); + setFieldName(field.getName()); + PsiClass psiClass = field.getContainingClass(); + if (psiClass != null) { + getProperties().myClassName = psiClass.getQualifiedName(); + } myIsStatic = field.hasModifierProperty(PsiModifier.STATIC); } if (myIsStatic) { - INSTANCE_FILTERS_ENABLED = false; + setInstanceFiltersEnabled(false); } } @@ -181,20 +179,21 @@ public class FieldBreakpoint extends BreakpointWithHighlighter { ReferenceType refType) { VirtualMachineProxy vm = debugProcess.getVirtualMachineProxy(); try { - Field field = refType.fieldByName(myFieldName); + Field field = refType.fieldByName(getFieldName()); if (field == null) { - debugProcess.getRequestsManager().setInvalid(this, DebuggerBundle.message("error.invalid.breakpoint.missing.field.in.class", myFieldName, refType.name())); + debugProcess.getRequestsManager().setInvalid(this, DebuggerBundle.message("error.invalid.breakpoint.missing.field.in.class", + getFieldName(), refType.name())); return; } RequestManagerImpl manager = debugProcess.getRequestsManager(); - if (WATCH_MODIFICATION && vm.canWatchFieldModification()) { + if (isWatchModification() && vm.canWatchFieldModification()) { ModificationWatchpointRequest request = manager.createModificationWatchpointRequest(this, field); debugProcess.getRequestsManager().enableRequest(request); if (LOG.isDebugEnabled()) { LOG.debug("Modification request added"); } } - if (WATCH_ACCESS && vm.canWatchFieldAccess()) { + if (isWatchAccess() && vm.canWatchFieldAccess()) { AccessWatchpointRequest request = manager.createAccessWatchpointRequest(this, field); debugProcess.getRequestsManager().enableRequest(request); if (LOG.isDebugEnabled()) { @@ -284,11 +283,11 @@ public class FieldBreakpoint extends BreakpointWithHighlighter { return DebuggerBundle.message("status.breakpoint.invalid"); } final String className = getClassName(); - return className != null && !className.isEmpty() ? className + "." + myFieldName : myFieldName; + return className != null && !className.isEmpty() ? className + "." + getFieldName() : getFieldName(); } - public static FieldBreakpoint create(@NotNull Project project, @NotNull Document document, int lineIndex, String fieldName) { - FieldBreakpoint breakpoint = new FieldBreakpoint(project, createHighlighter(project, document, lineIndex), fieldName); + public static FieldBreakpoint create(@NotNull Project project, String fieldName, XBreakpoint xBreakpoint) { + FieldBreakpoint breakpoint = new FieldBreakpoint(project, fieldName, xBreakpoint); return (FieldBreakpoint)breakpoint.init(); } @@ -308,39 +307,39 @@ public class FieldBreakpoint extends BreakpointWithHighlighter { return field == getPsiField(); } - protected static FieldBreakpoint create(@NotNull Project project, @NotNull Field field, ObjectReference object) { - String fieldName = field.name(); - int line = 0; - Document document = null; - try { - List locations = field.declaringType().allLineLocations(); - if(!locations.isEmpty()) { - Location location = (Location)locations.get(0); - line = location.lineNumber(); - VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(location.sourcePath()); - if(file != null) { - PsiFile psiFile = PsiManager.getInstance(project).findFile(file); - if(psiFile != null) { - document = PsiDocumentManager.getInstance(project).getDocument(psiFile); - } - } - } - } - catch (AbsentInformationException e) { - LOG.debug(e); - } - catch (InternalError e) { - LOG.debug(e); - } - - if(document == null) return null; - - FieldBreakpoint fieldBreakpoint = new FieldBreakpoint(project, createHighlighter(project, document, line), fieldName); - if (!fieldBreakpoint.isStatic()) { - fieldBreakpoint.addInstanceFilter(object.uniqueID()); - } - return (FieldBreakpoint)fieldBreakpoint.init(); - } + //protected static FieldBreakpoint create(@NotNull Project project, @NotNull Field field, ObjectReference object, XBreakpoint xBreakpoint) { + // String fieldName = field.name(); + // int line = 0; + // Document document = null; + // try { + // List locations = field.declaringType().allLineLocations(); + // if(!locations.isEmpty()) { + // Location location = (Location)locations.get(0); + // line = location.lineNumber(); + // VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(location.sourcePath()); + // if(file != null) { + // PsiFile psiFile = PsiManager.getInstance(project).findFile(file); + // if(psiFile != null) { + // document = PsiDocumentManager.getInstance(project).getDocument(psiFile); + // } + // } + // } + // } + // catch (AbsentInformationException e) { + // LOG.debug(e); + // } + // catch (InternalError e) { + // LOG.debug(e); + // } + // + // if(document == null) return null; + // + // FieldBreakpoint fieldBreakpoint = new FieldBreakpoint(project, createHighlighter(project, document, line), fieldName, xBreakpoint); + // if (!fieldBreakpoint.isStatic()) { + // fieldBreakpoint.addInstanceFilter(object.uniqueID()); + // } + // return (FieldBreakpoint)fieldBreakpoint.init(); + //} public static PsiField findField(Project project, Document document, int offset) { PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document); @@ -373,21 +372,41 @@ public class FieldBreakpoint extends BreakpointWithHighlighter { public void readExternal(@NotNull Element breakpointNode) throws InvalidDataException { super.readExternal(breakpointNode); //noinspection HardCodedStringLiteral - myFieldName = breakpointNode.getAttributeValue("field_name"); - if(myFieldName == null) { + setFieldName(breakpointNode.getAttributeValue("field_name")); + if(getFieldName() == null) { throw new InvalidDataException("No field name for field breakpoint"); } + try { + getProperties().WATCH_MODIFICATION = Boolean.valueOf(JDOMExternalizerUtil.readField(breakpointNode, "WATCH_MODIFICATION")); + } catch (Exception e) { + } + try { + getProperties().WATCH_ACCESS = Boolean.valueOf(JDOMExternalizerUtil.readField(breakpointNode, "WATCH_ACCESS")); + } catch (Exception e) { + } } - - @Override - @SuppressWarnings({"HardCodedStringLiteral"}) - public void writeExternal(@NotNull Element parentNode) throws WriteExternalException { - super.writeExternal(parentNode); - parentNode.setAttribute("field_name", getFieldName()); - } + // + //@Override + //@SuppressWarnings({"HardCodedStringLiteral"}) + //public void writeExternal(@NotNull Element parentNode) throws WriteExternalException { + // super.writeExternal(parentNode); + // parentNode.setAttribute("field_name", getFieldName()); + //} @Override public PsiElement getEvaluationElement() { return getPsiClass(); } + + private boolean isWatchModification() { + return getProperties().WATCH_MODIFICATION; + } + + private boolean isWatchAccess() { + return getProperties().WATCH_ACCESS; + } + + private void setFieldName(String fieldName) { + getProperties().myFieldName = fieldName; + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointFactory.java deleted file mode 100644 index 1bdef0c862e7..000000000000 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointFactory.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.debugger.ui.breakpoints; - -import com.intellij.CommonBundle; -import com.intellij.debugger.DebuggerBundle; -import com.intellij.debugger.DebuggerManagerEx; -import com.intellij.debugger.HelpID; -import com.intellij.icons.AllIcons; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.Ref; -import com.intellij.psi.*; -import com.intellij.psi.search.GlobalSearchScope; -import org.jdom.Element; - -import javax.swing.*; - -/** - * @author Eugene Zhuravlev - * Date: Apr 26, 2005 - */ -public class FieldBreakpointFactory extends BreakpointFactory{ - public Breakpoint createBreakpoint(Project project, final Element element) { - return new FieldBreakpoint(project); - } - - public Icon getIcon() { - return AllIcons.Debugger.Db_field_breakpoint; - } - - public Icon getDisabledIcon() { - return AllIcons.Debugger.Db_disabled_field_breakpoint; - } - - @Override - protected String getHelpID() { - return HelpID.FIELD_WATCHPOINTS; - } - - @Override - public String getDisplayName() { - return DebuggerBundle.message("field.watchpoints.tab.title"); - } - - @Override - public BreakpointPropertiesPanel createBreakpointPropertiesPanel(Project project, boolean compact) { - return new FieldBreakpointPropertiesPanel(project, compact); - } - - public Key<FieldBreakpoint> getBreakpointCategory() { - return FieldBreakpoint.CATEGORY; - } - - @Override - public Breakpoint addBreakpoint(final Project project) { - final Ref<Breakpoint> result = Ref.create(null); - AddFieldBreakpointDialog dialog = new AddFieldBreakpointDialog(project) { - protected boolean validateData() { - String className = getClassName(); - if (className.length() == 0) { - Messages.showMessageDialog(project, DebuggerBundle.message("error.field.breakpoint.class.name.not.specified"), - DebuggerBundle.message("add.field.breakpoint.dialog.title"), Messages.getErrorIcon()); - return false; - } - String fieldName = getFieldName(); - if (fieldName.length() == 0) { - Messages.showMessageDialog(project, DebuggerBundle.message("error.field.breakpoint.field.name.not.specified"), - DebuggerBundle.message("add.field.breakpoint.dialog.title"), Messages.getErrorIcon()); - return false; - } - PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass(className, GlobalSearchScope.allScope(project)); - if (psiClass != null) { - PsiFile psiFile = psiClass.getContainingFile(); - Document document = PsiDocumentManager.getInstance(project).getDocument(psiFile); - if(document != null) { - PsiField field = psiClass.findFieldByName(fieldName, true); - if(field != null) { - int line = document.getLineNumber(field.getTextOffset()); - FieldBreakpoint fieldBreakpoint = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().addFieldBreakpoint(document, line, fieldName); - if (fieldBreakpoint != null) { - result.set(fieldBreakpoint); - return true; - } - } - else { - Messages.showMessageDialog(project, - DebuggerBundle.message("error.field.breakpoint.field.not.found", className, fieldName, fieldName), - CommonBundle.getErrorTitle(), - Messages.getErrorIcon() - ); - } - } - } else { - Messages.showMessageDialog(project, - DebuggerBundle.message("error.field.breakpoint.class.sources.not.found", className, fieldName, className), - CommonBundle.getErrorTitle(), - Messages.getErrorIcon() - ); - } - return false; - } - }; - dialog.show(); - return result.get(); - } - - @Override - public boolean canAddBreakpoints() { - return true; - } -} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java index bec12645dd80..4d0bec2e165b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java @@ -21,24 +21,30 @@ package com.intellij.debugger.ui.breakpoints; import com.intellij.debugger.DebuggerBundle; -import com.intellij.openapi.project.Project; import com.intellij.ui.IdeBorderFactory; import com.intellij.util.ui.DialogUtil; +import com.intellij.xdebugger.breakpoints.XLineBreakpoint; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.java.debugger.breakpoints.properties.JavaFieldBreakpointProperties; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -public class FieldBreakpointPropertiesPanel extends BreakpointPropertiesPanel { +public class FieldBreakpointPropertiesPanel extends XBreakpointCustomPropertiesPanel<XLineBreakpoint<JavaFieldBreakpointProperties>> { private JCheckBox myWatchAccessCheckBox; private JCheckBox myWatchModificationCheckBox; - public FieldBreakpointPropertiesPanel(final Project project, boolean compact) { - super(project, FieldBreakpoint.CATEGORY, compact); - } + //public FieldBreakpointPropertiesPanel(final Project project, boolean compact) { + // super(project, FieldBreakpoint.CATEGORY, compact); + //} + - protected JComponent createSpecialBox() { + @NotNull + @Override + public JComponent getComponent() { JPanel _panel; JPanel _panel0; myWatchAccessCheckBox = new JCheckBox(DebuggerBundle.message("label.filed.breakpoint.properties.panel.field.access")); @@ -86,20 +92,15 @@ public class FieldBreakpointPropertiesPanel extends BreakpointPropertiesPanel { return _panel; } - public void initFrom(Breakpoint breakpoint, boolean moreOptionsVisible) { - super.initFrom(breakpoint, moreOptionsVisible); - FieldBreakpoint fieldBreakpoint = (FieldBreakpoint)breakpoint; - - myWatchAccessCheckBox.setSelected(fieldBreakpoint.WATCH_ACCESS); - myWatchModificationCheckBox.setSelected(fieldBreakpoint.WATCH_MODIFICATION); + @Override + public void loadFrom(@NotNull XLineBreakpoint<JavaFieldBreakpointProperties> breakpoint) { + myWatchAccessCheckBox.setSelected(breakpoint.getProperties().WATCH_ACCESS); + myWatchModificationCheckBox.setSelected(breakpoint.getProperties().WATCH_MODIFICATION); } - public void saveTo(Breakpoint breakpoint) { - FieldBreakpoint fieldBreakpoint = (FieldBreakpoint)breakpoint; - - fieldBreakpoint.WATCH_ACCESS = myWatchAccessCheckBox.isSelected(); - fieldBreakpoint.WATCH_MODIFICATION = myWatchModificationCheckBox.isSelected(); - - super.saveTo(breakpoint); + @Override + public void saveTo(@NotNull XLineBreakpoint<JavaFieldBreakpointProperties> breakpoint) { + breakpoint.getProperties().WATCH_ACCESS = myWatchAccessCheckBox.isSelected(); + breakpoint.getProperties().WATCH_MODIFICATION = myWatchModificationCheckBox.isSelected(); } }
\ No newline at end of file diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestor.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestor.java index 8aa57bd351d8..6a628f189bc5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestor.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,250 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/** - * class FilteredRequestor - * @author Jeka - */ package com.intellij.debugger.ui.breakpoints; -import com.intellij.debugger.*; -import com.intellij.debugger.engine.ContextUtil; -import com.intellij.debugger.engine.DebugProcessImpl; -import com.intellij.debugger.engine.evaluation.*; -import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl; -import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator; +import com.intellij.debugger.InstanceFilter; import com.intellij.debugger.engine.requests.LocatableEventRequestor; -import com.intellij.debugger.impl.DebuggerUtilsEx; -import com.intellij.debugger.settings.DebuggerSettings; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.*; -import com.intellij.psi.PsiElement; import com.intellij.ui.classFilter.ClassFilter; -import com.sun.jdi.BooleanValue; -import com.sun.jdi.ObjectReference; -import com.sun.jdi.VMDisconnectedException; -import com.sun.jdi.Value; -import com.sun.jdi.event.LocatableEvent; -import org.jdom.Element; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; - -public abstract class FilteredRequestor implements LocatableEventRequestor, JDOMExternalizable { - - public String SUSPEND_POLICY = DebuggerSettings.SUSPEND_ALL; - public boolean SUSPEND = true; - - public boolean COUNT_FILTER_ENABLED = false; - public int COUNT_FILTER = 0; - - public boolean CONDITION_ENABLED = false; - private TextWithImports myCondition; - - public boolean CLASS_FILTERS_ENABLED = false; - private ClassFilter[] myClassFilters = ClassFilter.EMPTY_ARRAY; - private ClassFilter[] myClassExclusionFilters = ClassFilter.EMPTY_ARRAY; - - public boolean INSTANCE_FILTERS_ENABLED = false; - private InstanceFilter[] myInstanceFilters = InstanceFilter.EMPTY_ARRAY; - - @NonNls private static final String FILTER_OPTION_NAME = "filter"; - @NonNls private static final String EXCLUSION_FILTER_OPTION_NAME = "exclusion_filter"; - @NonNls private static final String INSTANCE_ID_OPTION_NAME = "instance_id"; - @NonNls private static final String CONDITION_OPTION_NAME = "CONDITION"; - protected final Project myProject; - - public FilteredRequestor(@NotNull Project project) { - myProject = project; - myCondition = new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, ""); - } - - public InstanceFilter[] getInstanceFilters() { - return myInstanceFilters; - } - - public void setInstanceFilters(InstanceFilter[] instanceFilters) { - myInstanceFilters = instanceFilters != null? instanceFilters : InstanceFilter.EMPTY_ARRAY; - } - - public String getSuspendPolicy() { - return SUSPEND? SUSPEND_POLICY : DebuggerSettings.SUSPEND_NONE; - } - - /** - * @return true if the ID was added or false otherwise - */ - private boolean hasObjectID(long id) { - for (InstanceFilter instanceFilter : myInstanceFilters) { - if (instanceFilter.getId() == id) { - return true; - } - } - return false; - } - - protected void addInstanceFilter(long l) { - final InstanceFilter[] filters = new InstanceFilter[myInstanceFilters.length + 1]; - System.arraycopy(myInstanceFilters, 0, filters, 0, myInstanceFilters.length); - filters[myInstanceFilters.length] = InstanceFilter.create(String.valueOf(l)); - myInstanceFilters = filters; - } - public final ClassFilter[] getClassFilters() { - return myClassFilters; - } - - public final void setClassFilters(ClassFilter[] classFilters) { - myClassFilters = classFilters != null? classFilters : ClassFilter.EMPTY_ARRAY; - } - - public ClassFilter[] getClassExclusionFilters() { - return myClassExclusionFilters; - } - - public void setClassExclusionFilters(ClassFilter[] classExclusionFilters) { - myClassExclusionFilters = classExclusionFilters != null? classExclusionFilters : ClassFilter.EMPTY_ARRAY; - } - - public void readExternal(Element parentNode) throws InvalidDataException { - DefaultJDOMExternalizer.readExternal(this, parentNode); - if (DebuggerSettings.SUSPEND_NONE.equals(SUSPEND_POLICY)) { // compatibility with older format - SUSPEND = false; - SUSPEND_POLICY = DebuggerSettings.SUSPEND_ALL; - } - String condition = JDOMExternalizerUtil.readField(parentNode, CONDITION_OPTION_NAME); - if (condition != null) { - setCondition(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, condition)); - } - - myClassFilters = DebuggerUtilsEx.readFilters(parentNode.getChildren(FILTER_OPTION_NAME)); - myClassExclusionFilters = DebuggerUtilsEx.readFilters(parentNode.getChildren(EXCLUSION_FILTER_OPTION_NAME)); - - final ClassFilter [] instanceFilters = DebuggerUtilsEx.readFilters(parentNode.getChildren(INSTANCE_ID_OPTION_NAME)); - final List<InstanceFilter> iFilters = new ArrayList<InstanceFilter>(instanceFilters.length); - - for (ClassFilter instanceFilter : instanceFilters) { - try { - iFilters.add(InstanceFilter.create(instanceFilter)); - } - catch (Exception e) { - } - } - myInstanceFilters = iFilters.isEmpty() ? InstanceFilter.EMPTY_ARRAY : iFilters.toArray(new InstanceFilter[iFilters.size()]); - } - - public void writeExternal(Element parentNode) throws WriteExternalException { - DefaultJDOMExternalizer.writeExternal(this, parentNode); - JDOMExternalizerUtil.writeField(parentNode, CONDITION_OPTION_NAME, getCondition().toExternalForm()); - DebuggerUtilsEx.writeFilters(parentNode, FILTER_OPTION_NAME, myClassFilters); - DebuggerUtilsEx.writeFilters(parentNode, EXCLUSION_FILTER_OPTION_NAME, myClassExclusionFilters); - DebuggerUtilsEx.writeFilters(parentNode, INSTANCE_ID_OPTION_NAME, InstanceFilter.createClassFilters(myInstanceFilters)); - } - - public boolean evaluateCondition(final EvaluationContextImpl context, LocatableEvent event) throws EvaluateException { - if(COUNT_FILTER_ENABLED) { - final DebugProcessImpl debugProcess = context.getDebugProcess(); - debugProcess.getVirtualMachineProxy().suspend(); - debugProcess.getRequestsManager().deleteRequest(this); - ((Breakpoint)this).createRequest(debugProcess); - debugProcess.getVirtualMachineProxy().resume(); - } - if (INSTANCE_FILTERS_ENABLED) { - Value value = context.getThisObject(); - if (value != null) { // non-static - ObjectReference reference = (ObjectReference)value; - if(!hasObjectID(reference.uniqueID())) { - return false; - } - } - } - - if (CLASS_FILTERS_ENABLED) { - String typeName = calculateEventClass(context, event); - if (!typeMatchesClassFilters(typeName)) return false; - } - - if (CONDITION_ENABLED && getCondition() != null && !"".equals(getCondition().getText())) { - try { - ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(context.getProject(), new EvaluatingComputable<ExpressionEvaluator>() { - public ExpressionEvaluator compute() throws EvaluateException { - final SourcePosition contextSourcePosition = ContextUtil.getSourcePosition(context); - // IMPORTANT: calculate context psi element basing on the location where the exception - // has been hit, not on the location where it was set. (For line breakpoints these locations are the same, however, - // for method, exception and field breakpoints these locations differ) - PsiElement contextPsiElement = ContextUtil.getContextElement(contextSourcePosition); - if (contextPsiElement == null) { - contextPsiElement = getEvaluationElement(); // as a last resort - } - return EvaluatorBuilderImpl.build(getCondition(), contextPsiElement, contextSourcePosition); - } - }); - final Value value = evaluator.evaluate(context); - if (!(value instanceof BooleanValue)) { - throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.boolean.expected")); - } - if(!((BooleanValue)value).booleanValue()) { - return false; - } - } - catch (EvaluateException ex) { - if(ex.getCause() instanceof VMDisconnectedException) { - return false; - } - throw EvaluateExceptionUtil.createEvaluateException( - DebuggerBundle.message("error.failed.evaluating.breakpoint.condition", getCondition(), ex.getMessage()) - ); - } - return true; - } - - return true; - } - - protected String calculateEventClass(EvaluationContextImpl context, LocatableEvent event) throws EvaluateException { - return event.location().declaringType().name(); - } - - private boolean typeMatchesClassFilters(@Nullable String typeName) { - if (typeName == null) { - return true; - } - boolean matches = false, hasEnabled = false; - for (ClassFilter classFilter : getClassFilters()) { - if (classFilter.isEnabled()) { - hasEnabled = true; - if (classFilter.matches(typeName)) { - matches = true; - break; - } - } - } - if(hasEnabled && !matches) { - return false; - } - for (ClassFilter classFilter : getClassExclusionFilters()) { - if (classFilter.isEnabled() && classFilter.matches(typeName)) { - return false; - } - } - return true; - } - - public abstract PsiElement getEvaluationElement(); +/** + * @author egor + */ +public interface FilteredRequestor extends LocatableEventRequestor { + String getSuspendPolicy(); - public TextWithImports getCondition() { - return myCondition; - } + boolean isInstanceFiltersEnabled(); + InstanceFilter[] getInstanceFilters(); - public void setCondition(TextWithImports condition) { - myCondition = condition; - } + boolean isCountFilterEnabled(); + int getCountFilter(); - public Project getProject() { - return myProject; - } + boolean isClassFiltersEnabled(); + ClassFilter[] getClassFilters(); + ClassFilter[] getClassExclusionFilters(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestorImpl.java new file mode 100644 index 000000000000..496292881354 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestorImpl.java @@ -0,0 +1,243 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * class FilteredRequestorImpl + * @author Jeka + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.InstanceFilter; +import com.intellij.debugger.engine.evaluation.*; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.*; +import com.intellij.psi.PsiElement; +import com.intellij.ui.classFilter.ClassFilter; +import com.sun.jdi.event.LocatableEvent; +import org.jdom.Element; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/* + * Not used any more, since move to xBreakpoints + */ +public class FilteredRequestorImpl implements JDOMExternalizable, FilteredRequestor { + + public String SUSPEND_POLICY = DebuggerSettings.SUSPEND_ALL; + public boolean SUSPEND = true; + + public boolean COUNT_FILTER_ENABLED = false; + public int COUNT_FILTER = 0; + + public boolean CONDITION_ENABLED = false; + private TextWithImports myCondition; + + public boolean CLASS_FILTERS_ENABLED = false; + private ClassFilter[] myClassFilters = ClassFilter.EMPTY_ARRAY; + private ClassFilter[] myClassExclusionFilters = ClassFilter.EMPTY_ARRAY; + + public boolean INSTANCE_FILTERS_ENABLED = false; + private InstanceFilter[] myInstanceFilters = InstanceFilter.EMPTY_ARRAY; + + @NonNls private static final String FILTER_OPTION_NAME = "filter"; + @NonNls private static final String EXCLUSION_FILTER_OPTION_NAME = "exclusion_filter"; + @NonNls private static final String INSTANCE_ID_OPTION_NAME = "instance_id"; + @NonNls private static final String CONDITION_OPTION_NAME = "CONDITION"; + protected final Project myProject; + + public FilteredRequestorImpl(@NotNull Project project) { + myProject = project; + myCondition = new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, ""); + } + + public InstanceFilter[] getInstanceFilters() { + return myInstanceFilters; + } + + public void setInstanceFilters(InstanceFilter[] instanceFilters) { + myInstanceFilters = instanceFilters != null? instanceFilters : InstanceFilter.EMPTY_ARRAY; + } + + public String getSuspendPolicy() { + return SUSPEND? SUSPEND_POLICY : DebuggerSettings.SUSPEND_NONE; + } + + /** + * @return true if the ID was added or false otherwise + */ + private boolean hasObjectID(long id) { + for (InstanceFilter instanceFilter : myInstanceFilters) { + if (instanceFilter.getId() == id) { + return true; + } + } + return false; + } + + protected void addInstanceFilter(long l) { + final InstanceFilter[] filters = new InstanceFilter[myInstanceFilters.length + 1]; + System.arraycopy(myInstanceFilters, 0, filters, 0, myInstanceFilters.length); + filters[myInstanceFilters.length] = InstanceFilter.create(String.valueOf(l)); + myInstanceFilters = filters; + } + + public final ClassFilter[] getClassFilters() { + return myClassFilters; + } + + public final void setClassFilters(ClassFilter[] classFilters) { + myClassFilters = classFilters != null? classFilters : ClassFilter.EMPTY_ARRAY; + } + + public ClassFilter[] getClassExclusionFilters() { + return myClassExclusionFilters; + } + + public void setClassExclusionFilters(ClassFilter[] classExclusionFilters) { + myClassExclusionFilters = classExclusionFilters != null? classExclusionFilters : ClassFilter.EMPTY_ARRAY; + } + + public void readTo(Element parentNode, Breakpoint breakpoint) throws InvalidDataException { + readExternal(parentNode); + if (SUSPEND) { + breakpoint.setSuspendPolicy(SUSPEND_POLICY); + } + else { + breakpoint.setSuspendPolicy(DebuggerSettings.SUSPEND_NONE); + } + + breakpoint.setCountFilterEnabled(COUNT_FILTER_ENABLED); + breakpoint.setCountFilter(COUNT_FILTER); + + breakpoint.setCondition(CONDITION_ENABLED ? myCondition : null); + + breakpoint.setClassFiltersEnabled(CLASS_FILTERS_ENABLED); + breakpoint.setClassFilters(getClassFilters()); + breakpoint.setClassExclusionFilters(getClassExclusionFilters()); + + breakpoint.setInstanceFiltersEnabled(INSTANCE_FILTERS_ENABLED); + breakpoint.setInstanceFilters(getInstanceFilters()); + } + + public void readExternal(Element parentNode) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, parentNode); + if (DebuggerSettings.SUSPEND_NONE.equals(SUSPEND_POLICY)) { // compatibility with older format + SUSPEND = false; + SUSPEND_POLICY = DebuggerSettings.SUSPEND_ALL; + } + String condition = JDOMExternalizerUtil.readField(parentNode, CONDITION_OPTION_NAME); + if (condition != null) { + setCondition(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, condition)); + } + + myClassFilters = DebuggerUtilsEx.readFilters(parentNode.getChildren(FILTER_OPTION_NAME)); + myClassExclusionFilters = DebuggerUtilsEx.readFilters(parentNode.getChildren(EXCLUSION_FILTER_OPTION_NAME)); + + final ClassFilter [] instanceFilters = DebuggerUtilsEx.readFilters(parentNode.getChildren(INSTANCE_ID_OPTION_NAME)); + final List<InstanceFilter> iFilters = new ArrayList<InstanceFilter>(instanceFilters.length); + + for (ClassFilter instanceFilter : instanceFilters) { + try { + iFilters.add(InstanceFilter.create(instanceFilter)); + } + catch (Exception e) { + } + } + myInstanceFilters = iFilters.isEmpty() ? InstanceFilter.EMPTY_ARRAY : iFilters.toArray(new InstanceFilter[iFilters.size()]); + } + + public void writeExternal(Element parentNode) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, parentNode); + JDOMExternalizerUtil.writeField(parentNode, CONDITION_OPTION_NAME, getCondition().toExternalForm()); + DebuggerUtilsEx.writeFilters(parentNode, FILTER_OPTION_NAME, myClassFilters); + DebuggerUtilsEx.writeFilters(parentNode, EXCLUSION_FILTER_OPTION_NAME, myClassExclusionFilters); + DebuggerUtilsEx.writeFilters(parentNode, INSTANCE_ID_OPTION_NAME, InstanceFilter.createClassFilters(myInstanceFilters)); + } + + protected String calculateEventClass(EvaluationContextImpl context, LocatableEvent event) throws EvaluateException { + return event.location().declaringType().name(); + } + + private boolean typeMatchesClassFilters(@Nullable String typeName) { + if (typeName == null) { + return true; + } + boolean matches = false, hasEnabled = false; + for (ClassFilter classFilter : getClassFilters()) { + if (classFilter.isEnabled()) { + hasEnabled = true; + if (classFilter.matches(typeName)) { + matches = true; + break; + } + } + } + if(hasEnabled && !matches) { + return false; + } + for (ClassFilter classFilter : getClassExclusionFilters()) { + if (classFilter.isEnabled() && classFilter.matches(typeName)) { + return false; + } + } + return true; + } + + public PsiElement getEvaluationElement() { + return null; + } + + public TextWithImports getCondition() { + return myCondition; + } + + public void setCondition(TextWithImports condition) { + myCondition = condition; + } + + public Project getProject() { + return myProject; + } + + public boolean isCountFilterEnabled() { + return COUNT_FILTER_ENABLED; + } + + public int getCountFilter() { + return COUNT_FILTER; + } + + public boolean isClassFiltersEnabled() { + return CLASS_FILTERS_ENABLED; + } + + public boolean isInstanceFiltersEnabled() { + return INSTANCE_FILTERS_ENABLED; + } + + @Override + public boolean processLocatableEvent(SuspendContextCommandImpl action, LocatableEvent event) + throws EventProcessingException { + return false; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java deleted file mode 100644 index ec3577cbae0a..000000000000 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.debugger.ui.breakpoints; - -import com.intellij.debugger.DebuggerManagerEx; -import com.intellij.debugger.SourcePosition; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.ui.SimpleColoredComponent; -import com.intellij.ui.SimpleTextAttributes; -import com.intellij.ui.popup.util.DetailView; -import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointItem; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; - -class JavaBreakpointItem extends BreakpointItem { - private final Breakpoint myBreakpoint; - private BreakpointFactory myBreakpointFactory; - private BreakpointPropertiesPanel myBreakpointPropertiesPanel; - - public JavaBreakpointItem(@Nullable BreakpointFactory breakpointFactory, Breakpoint breakpoint) { - myBreakpointFactory = breakpointFactory; - myBreakpoint = breakpoint; - } - - @Override - public void setupGenericRenderer(SimpleColoredComponent renderer, boolean plainView) { - if (plainView) { - renderer.setIcon(myBreakpoint.getIcon()); - } - renderer.append(plainView ? StringUtil.shortenTextWithEllipsis(myBreakpoint.getShortName(), 60, 0) : myBreakpoint.getDisplayName(), - isEnabled() ? SimpleTextAttributes.REGULAR_ATTRIBUTES : SimpleTextAttributes.GRAY_ATTRIBUTES); - } - - @Override - public Icon getIcon() { - return myBreakpoint.getIcon(); - } - - @Override - public String getDisplayText() { - return myBreakpoint.getDisplayName(); - } - - @Override - public String speedSearchText() { - return myBreakpoint.getDisplayName(); - } - - @Override - public String footerText() { - return myBreakpoint.getDisplayName(); - } - - @Override - protected void doUpdateDetailView(DetailView panel, boolean editorOnly) { - //saveState(); - if (myBreakpointPropertiesPanel != null) { - myBreakpointPropertiesPanel.dispose(); - myBreakpointPropertiesPanel = null; - } - - if (!editorOnly) { - myBreakpointPropertiesPanel = myBreakpointFactory != null ? myBreakpointFactory - .createBreakpointPropertiesPanel(myBreakpoint.getProject(), false) : null; - - if (myBreakpointPropertiesPanel != null) { - myBreakpointPropertiesPanel.initFrom(myBreakpoint, true); - - final JPanel mainPanel = myBreakpointPropertiesPanel.getPanel(); - panel.setPropertiesPanel(mainPanel); - } - else { - panel.setPropertiesPanel(null); - } - } - - if (myBreakpoint instanceof BreakpointWithHighlighter) { - SourcePosition sourcePosition = ((BreakpointWithHighlighter)myBreakpoint).getSourcePosition(); - VirtualFile virtualFile = sourcePosition.getFile().getVirtualFile(); - showInEditor(panel, virtualFile, sourcePosition.getLine()); - } else { - panel.clearEditor(); - } - if (myBreakpointPropertiesPanel != null) { - myBreakpointPropertiesPanel.setDetailView(panel); - } - } - - @Override - public void navigate(boolean requestFocus) { - if (myBreakpoint instanceof BreakpointWithHighlighter) { - ((BreakpointWithHighlighter)myBreakpoint).getSourcePosition().navigate(requestFocus); - } - } - - @Override - public boolean canNavigate() { - return myBreakpoint instanceof BreakpointWithHighlighter && ((BreakpointWithHighlighter)myBreakpoint).getSourcePosition().canNavigate(); - } - - @Override - public boolean canNavigateToSource() { - return myBreakpoint instanceof BreakpointWithHighlighter && - ((BreakpointWithHighlighter)myBreakpoint).getSourcePosition().canNavigateToSource(); - } - - @Override - public boolean allowedToRemove() { - return myBreakpointFactory != null && myBreakpointFactory.breakpointCanBeRemoved(myBreakpoint); - } - - @Override - public void removed(Project project) { - dispose(); - DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().removeBreakpoint(myBreakpoint); - } - - @Override - public void saveState() { - if (myBreakpointPropertiesPanel != null) { - myBreakpointPropertiesPanel.saveTo(myBreakpoint); - } - } - - @Override - public Object getBreakpoint() { - return myBreakpoint; - } - - @Override - public boolean isEnabled() { - return myBreakpoint.ENABLED; - } - - @Override - public void setEnabled(boolean state) { - myBreakpoint.ENABLED = state; - myBreakpoint.updateUI(); - DebuggerManagerEx.getInstanceEx(myBreakpoint.getProject()).getBreakpointManager().fireBreakpointChanged(myBreakpoint); - } - - @Override - public boolean isDefaultBreakpoint() { - return myBreakpoint.getCategory().equals(ExceptionBreakpoint.CATEGORY); - } - - @Override - protected void dispose() { - if (myBreakpointPropertiesPanel != null) { - myBreakpointPropertiesPanel.dispose(); - myBreakpointPropertiesPanel = null; - } - } - - @Override - public int compareTo(@NotNull BreakpointItem breakpointItem) { - final Object breakpoint = breakpointItem.getBreakpoint(); - if (breakpoint instanceof Breakpoint) { - return -getIndexOf(myBreakpoint) + getIndexOf((Breakpoint)breakpoint); - } - return getDisplayText().compareTo(breakpointItem.getDisplayText()); - } - - private int getIndexOf(Breakpoint breakpoint) { - return DebuggerManagerEx.getInstanceEx(myBreakpoint.getProject()).getBreakpointManager().getBreakpoints().indexOf(breakpoint); - } -} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointType.java index 802657b44fd9..2776032a2f4f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointPropertiesPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,17 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/* - * Class LineBreakpointPropertiesPanel - * @author Jeka - */ package com.intellij.debugger.ui.breakpoints; import com.intellij.openapi.project.Project; +import com.intellij.xdebugger.breakpoints.XBreakpoint; +import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties; -public class LineBreakpointPropertiesPanel extends BreakpointPropertiesPanel { - public LineBreakpointPropertiesPanel(Project project, boolean compact) { - super(project, LineBreakpoint.CATEGORY, compact); - } -}
\ No newline at end of file +/** + * Base class for all Java breakpoint types + * @author egor + */ +public interface JavaBreakpointType<P extends JavaBreakpointProperties> { + Breakpoint createJavaBreakpoint(Project project, XBreakpoint<P> breakpoint); +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointTypeBase.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointTypeBase.java new file mode 100644 index 000000000000..0bb20d620c2d --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointTypeBase.java @@ -0,0 +1,75 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.ui.JavaDebuggerSupport; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.xdebugger.XDebuggerUtil; +import com.intellij.xdebugger.XSourcePosition; +import com.intellij.xdebugger.breakpoints.XBreakpoint; +import com.intellij.xdebugger.breakpoints.XBreakpointType; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; +import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.java.debugger.JavaDebuggerEditorsProvider; +import org.jetbrains.java.debugger.breakpoints.JavaBreakpointFiltersPanel; +import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties; + +/** + * Base class for non-line java breakpoint + * @author egor + */ +public abstract class JavaBreakpointTypeBase<T extends JavaBreakpointProperties> extends XBreakpointType<XBreakpoint<T>, T> { + protected JavaBreakpointTypeBase(@NonNls @NotNull String id, @Nls @NotNull String title) { + super(id, title, true); + } + + @Override + public final boolean isAddBreakpointButtonVisible() { + return true; + } + + @Nullable + @Override + public final XBreakpointCustomPropertiesPanel<XBreakpoint<T>> createCustomRightPropertiesPanel(@NotNull Project project) { + return new JavaBreakpointFiltersPanel<T, XBreakpoint<T>>(project); + } + + @Nullable + @Override + public final XDebuggerEditorsProvider getEditorsProvider(@NotNull XBreakpoint<T> breakpoint, @NotNull Project project) { + return new JavaDebuggerEditorsProvider(); + } + + @Nullable + @Override + public XSourcePosition getSourcePosition(@NotNull XBreakpoint<T> breakpoint) { + BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(JavaDebuggerSupport.getCurrentProject()).getBreakpointManager(); + Breakpoint javaBreakpoint = breakpointManager.findBreakpoint(breakpoint); + if (javaBreakpoint != null) { + PsiClass aClass = javaBreakpoint.getPsiClass(); + if (aClass != null && aClass.getContainingFile() != null) { + return XDebuggerUtil.getInstance().createPositionByOffset(aClass.getContainingFile().getVirtualFile(), aClass.getTextOffset()); + } + } + return null; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaExceptionBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaExceptionBreakpointType.java new file mode 100644 index 000000000000..d5d4b714875c --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaExceptionBreakpointType.java @@ -0,0 +1,138 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.HelpID; +import com.intellij.debugger.engine.JVMNameUtil; +import com.intellij.icons.AllIcons; +import com.intellij.ide.util.TreeClassChooser; +import com.intellij.ide.util.TreeClassChooserFactory; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiClassOwner; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.xdebugger.XDebuggerManager; +import com.intellij.xdebugger.breakpoints.XBreakpoint; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.java.debugger.breakpoints.properties.JavaExceptionBreakpointProperties; + +import javax.swing.*; + +/** + * @author Eugene Zhuravlev + * Date: Apr 26, 2005 + */ +public class JavaExceptionBreakpointType extends JavaBreakpointTypeBase<JavaExceptionBreakpointProperties> + implements JavaBreakpointType<JavaExceptionBreakpointProperties> { + public JavaExceptionBreakpointType() { + super("java-exception", DebuggerBundle.message("exception.breakpoints.tab.title")); + } + + @NotNull + @Override + public Icon getEnabledIcon() { + return AllIcons.Debugger.Db_exception_breakpoint; + } + + @NotNull + @Override + public Icon getDisabledIcon() { + return AllIcons.Debugger.Db_disabled_exception_breakpoint; + } + + //@Override + protected String getHelpID() { + return HelpID.EXCEPTION_BREAKPOINTS; + } + + //@Override + public String getDisplayName() { + return DebuggerBundle.message("exception.breakpoints.tab.title"); + } + + @Override + public String getDisplayText(XBreakpoint<JavaExceptionBreakpointProperties> breakpoint) { + String name = breakpoint.getProperties().myQualifiedName; + if (name != null) { + return DebuggerBundle.message("breakpoint.exception.breakpoint.display.name", name); + } + else { + return DebuggerBundle.message("breakpoint.any.exception.display.name"); + } + } + + @Nullable + @Override + public JavaExceptionBreakpointProperties createProperties() { + return new JavaExceptionBreakpointProperties(); + } + + @Nullable + @Override + public XBreakpointCustomPropertiesPanel<XBreakpoint<JavaExceptionBreakpointProperties>> createCustomPropertiesPanel() { + return new ExceptionBreakpointPropertiesPanel(); + } + + @Nullable + @Override + public XBreakpoint<JavaExceptionBreakpointProperties> createDefaultBreakpoint(@NotNull XBreakpointCreator<JavaExceptionBreakpointProperties> creator) { + return creator.createBreakpoint(new JavaExceptionBreakpointProperties()); + } + + //public Key<ExceptionBreakpoint> getBreakpointCategory() { + // return ExceptionBreakpoint.CATEGORY; + //} + + @Nullable + @Override + public XBreakpoint<JavaExceptionBreakpointProperties> addBreakpoint(final Project project, JComponent parentComponent) { + final PsiClass throwableClass = + JavaPsiFacade.getInstance(project).findClass("java.lang.Throwable", GlobalSearchScope.allScope(project)); + TreeClassChooser chooser = TreeClassChooserFactory.getInstance(project) + .createInheritanceClassChooser(DebuggerBundle.message("add.exception.breakpoint.classchooser.title"), + GlobalSearchScope.allScope(project), throwableClass, true, true, null); + chooser.showDialog(); + final PsiClass selectedClass = chooser.getSelected(); + final String qName = selectedClass == null ? null : JVMNameUtil.getNonAnonymousClassName(selectedClass); + + if (qName != null && qName.length() > 0) { + return ApplicationManager.getApplication().runWriteAction(new Computable<XBreakpoint<JavaExceptionBreakpointProperties>>() { + @Override + public XBreakpoint<JavaExceptionBreakpointProperties> compute() { + return XDebuggerManager.getInstance(project).getBreakpointManager().addBreakpoint( + JavaExceptionBreakpointType.this, new JavaExceptionBreakpointProperties(qName, ((PsiClassOwner)selectedClass.getContainingFile()).getPackageName())); + } + }); + } + return null; + } + + @Override + public Breakpoint createJavaBreakpoint(Project project, XBreakpoint<JavaExceptionBreakpointProperties> breakpoint) { + if (!XDebuggerManager.getInstance(project).getBreakpointManager().isDefaultBreakpoint(breakpoint)) { + return new ExceptionBreakpoint(project, breakpoint); + } + else { + return new AnyExceptionBreakpoint(project, breakpoint); + } + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java new file mode 100644 index 000000000000..74a6f2df61cc --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java @@ -0,0 +1,166 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.CommonBundle; +import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.HelpID; +import com.intellij.icons.AllIcons; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.xdebugger.XDebuggerManager; +import com.intellij.xdebugger.breakpoints.XBreakpoint; +import com.intellij.xdebugger.breakpoints.XLineBreakpoint; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.java.debugger.breakpoints.properties.JavaFieldBreakpointProperties; + +import javax.swing.*; + +/** + * @author Eugene Zhuravlev + * Date: Apr 26, 2005 + */ +public class JavaFieldBreakpointType extends JavaLineBreakpointTypeBase<JavaFieldBreakpointProperties> implements JavaBreakpointType { + public JavaFieldBreakpointType() { + super("java-field", DebuggerBundle.message("field.watchpoints.tab.title")); + } + + @NotNull + @Override + public Icon getEnabledIcon() { + return AllIcons.Debugger.Db_field_breakpoint; + } + + @NotNull + @Override + public Icon getDisabledIcon() { + return AllIcons.Debugger.Db_disabled_field_breakpoint; + } + + //@Override + protected String getHelpID() { + return HelpID.FIELD_WATCHPOINTS; + } + + //@Override + public String getDisplayName() { + return DebuggerBundle.message("field.watchpoints.tab.title"); + } + + @Override + public String getShortText(XLineBreakpoint<JavaFieldBreakpointProperties> breakpoint) { + return getText(breakpoint); + } + + public String getText(XLineBreakpoint<JavaFieldBreakpointProperties> breakpoint) { + //if(!isValid()) { + // return DebuggerBundle.message("status.breakpoint.invalid"); + //} + + JavaFieldBreakpointProperties properties = breakpoint.getProperties(); + final String className = properties.myClassName; + return className != null && !className.isEmpty() ? className + "." + properties.myFieldName : properties.myFieldName; + } + + @Nullable + @Override + public XBreakpointCustomPropertiesPanel<XLineBreakpoint<JavaFieldBreakpointProperties>> createCustomPropertiesPanel() { + return new FieldBreakpointPropertiesPanel(); + } + + @Nullable + @Override + public JavaFieldBreakpointProperties createProperties() { + return new JavaFieldBreakpointProperties(); + } + + @Nullable + @Override + public JavaFieldBreakpointProperties createBreakpointProperties(@NotNull VirtualFile file, int line) { + return new JavaFieldBreakpointProperties(); + } + + @Nullable + @Override + public XLineBreakpoint<JavaFieldBreakpointProperties> addBreakpoint(final Project project, JComponent parentComponent) { + final Ref<XLineBreakpoint> result = Ref.create(null); + AddFieldBreakpointDialog dialog = new AddFieldBreakpointDialog(project) { + protected boolean validateData() { + final String className = getClassName(); + if (className.length() == 0) { + Messages.showMessageDialog(project, DebuggerBundle.message("error.field.breakpoint.class.name.not.specified"), + DebuggerBundle.message("add.field.breakpoint.dialog.title"), Messages.getErrorIcon()); + return false; + } + final String fieldName = getFieldName(); + if (fieldName.length() == 0) { + Messages.showMessageDialog(project, DebuggerBundle.message("error.field.breakpoint.field.name.not.specified"), + DebuggerBundle.message("add.field.breakpoint.dialog.title"), Messages.getErrorIcon()); + return false; + } + PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass(className, GlobalSearchScope.allScope(project)); + if (psiClass != null) { + final PsiFile psiFile = psiClass.getContainingFile(); + Document document = PsiDocumentManager.getInstance(project).getDocument(psiFile); + if(document != null) { + PsiField field = psiClass.findFieldByName(fieldName, true); + if(field != null) { + final int line = document.getLineNumber(field.getTextOffset()); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + XLineBreakpoint<JavaFieldBreakpointProperties> fieldBreakpoint = XDebuggerManager.getInstance(project).getBreakpointManager() + .addLineBreakpoint(JavaFieldBreakpointType.this, psiFile.getVirtualFile().getUrl(), line, new JavaFieldBreakpointProperties(fieldName, className)); + result.set(fieldBreakpoint); + } + }); + return true; + } + else { + Messages.showMessageDialog(project, + DebuggerBundle.message("error.field.breakpoint.field.not.found", className, fieldName, fieldName), + CommonBundle.getErrorTitle(), + Messages.getErrorIcon() + ); + } + } + } else { + Messages.showMessageDialog(project, + DebuggerBundle.message("error.field.breakpoint.class.sources.not.found", className, fieldName, className), + CommonBundle.getErrorTitle(), + Messages.getErrorIcon() + ); + } + return false; + } + }; + dialog.show(); + return result.get(); + } + + @Override + public Breakpoint createJavaBreakpoint(Project project, XBreakpoint breakpoint) { + return new FieldBreakpoint(project, breakpoint); + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointType.java new file mode 100644 index 000000000000..99a37d4d3fbe --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointType.java @@ -0,0 +1,92 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.HelpID; +import com.intellij.icons.AllIcons; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.xdebugger.XDebuggerUtil; +import com.intellij.xdebugger.breakpoints.XBreakpoint; +import com.intellij.xdebugger.breakpoints.XLineBreakpoint; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties; +import org.jetbrains.java.debugger.breakpoints.properties.JavaLineBreakpointProperties; + +import javax.swing.*; +import java.util.List; + +/** + * Base class for java line-connected exceptions (line, method, field) + * @author egor + */ +public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase<JavaBreakpointProperties> implements JavaBreakpointType { + public JavaLineBreakpointType() { + super("java-line", DebuggerBundle.message("line.breakpoints.tab.title")); + } + + @NotNull + @Override + public Icon getEnabledIcon() { + return AllIcons.Debugger.Db_set_breakpoint; + } + + @NotNull + @Override + public Icon getDisabledIcon() { + return AllIcons.Debugger.Db_disabled_breakpoint; + } + + //@Override + protected String getHelpID() { + return HelpID.LINE_BREAKPOINTS; + } + + //@Override + public String getDisplayName() { + return DebuggerBundle.message("line.breakpoints.tab.title"); + } + + @Override + public List<XBreakpointGroupingRule<XLineBreakpoint<JavaBreakpointProperties>, ?>> getGroupingRules() { + return XDebuggerUtil.getInstance().getGroupingByFileRuleAsList(); + } + + @Nullable + @Override + public JavaBreakpointProperties createProperties() { + return new JavaLineBreakpointProperties(); + } + + @Nullable + @Override + public JavaBreakpointProperties createBreakpointProperties(@NotNull VirtualFile file, int line) { + return new JavaLineBreakpointProperties(); + } + + @Override + public Breakpoint createJavaBreakpoint(Project project, XBreakpoint breakpoint) { + return new LineBreakpoint(project, breakpoint); + } + + @Override + public int getPriority() { + return 100; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointTypeBase.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointTypeBase.java new file mode 100644 index 000000000000..08b26bb7280e --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointTypeBase.java @@ -0,0 +1,157 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.engine.DebuggerUtils; +import com.intellij.debugger.ui.JavaDebuggerSupport; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +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.util.PsiTreeUtil; +import com.intellij.util.Processor; +import com.intellij.xdebugger.XDebuggerUtil; +import com.intellij.xdebugger.breakpoints.XLineBreakpoint; +import com.intellij.xdebugger.breakpoints.XLineBreakpointType; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; +import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.java.debugger.JavaDebuggerEditorsProvider; +import org.jetbrains.java.debugger.breakpoints.JavaBreakpointFiltersPanel; +import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties; + +/** + * Base class for java line-connected exceptions (line, method, field) + * @author egor + */ +public abstract class JavaLineBreakpointTypeBase<P extends JavaBreakpointProperties> extends XLineBreakpointType<P> { + public JavaLineBreakpointTypeBase(@NonNls @NotNull String id, @Nls @NotNull String title) { + super(id, title); + } + + @Override + public boolean isAddBreakpointButtonVisible() { + return true; + } + + @Override + public final boolean isSuspendThreadSupported() { + return true; + } + + @Nullable + @Override + public final XBreakpointCustomPropertiesPanel<XLineBreakpoint<P>> createCustomRightPropertiesPanel(@NotNull Project project) { + return new JavaBreakpointFiltersPanel<P, XLineBreakpoint<P>>(project); + } + + @Nullable + @Override + public final XDebuggerEditorsProvider getEditorsProvider(@NotNull XLineBreakpoint<P> breakpoint, @NotNull Project project) { + return new JavaDebuggerEditorsProvider(); + } + + @Override + public String getDisplayText(XLineBreakpoint<P> breakpoint) { + BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(JavaDebuggerSupport.getCurrentProject()).getBreakpointManager(); + BreakpointWithHighlighter javaBreakpoint = (BreakpointWithHighlighter)breakpointManager.findBreakpoint(breakpoint); + if (javaBreakpoint != null) { + return javaBreakpoint.getDescription(); + } + else { + return super.getDisplayText(breakpoint); + } + } + + @Override + public final boolean canPutAt(@NotNull VirtualFile file, final int line, @NotNull Project project) { + PsiFile psiFile = PsiManager.getInstance(project).findFile(file); + // JSPX supports jvm debugging, but not in XHTML files + // JS has it's own breakpoints + if (psiFile == null || psiFile.getVirtualFile().getFileType() == StdFileTypes.XHTML || psiFile.getVirtualFile().getFileType() == StdFileTypes.JS) { + return false; + } + + FileType fileType = psiFile.getFileType(); + if (!StdFileTypes.CLASS.equals(fileType) && + !DebuggerUtils.supportsJVMDebugging(fileType) && + !DebuggerUtils.supportsJVMDebugging(psiFile)) { + return false; + } + + final Document document = FileDocumentManager.getInstance().getDocument(file); + final Ref<Class<? extends JavaLineBreakpointTypeBase>> result = Ref.create(); + XDebuggerUtil.getInstance().iterateLine(project, document, line, new Processor<PsiElement>() { + @Override + public boolean process(PsiElement element) { + // avoid comments + if ((element instanceof PsiWhiteSpace) || (PsiTreeUtil.getParentOfType(element, PsiComment.class, false) != null)) { + return true; + } + PsiElement parent = element; + while(element != null) { + // skip modifiers + if (element instanceof PsiModifierList) { + element = element.getParent(); + continue; + } + + final int offset = element.getTextOffset(); + if (offset >= 0) { + if (document.getLineNumber(offset) != line) { + break; + } + } + parent = element; + element = element.getParent(); + } + + if(parent instanceof PsiMethod) { + if (parent.getTextRange().getEndOffset() >= document.getLineEndOffset(line)) { + PsiCodeBlock body = ((PsiMethod)parent).getBody(); + if (body != null) { + PsiStatement[] statements = body.getStatements(); + if (statements.length > 0 && document.getLineNumber(statements[0].getTextOffset()) == line) { + result.set(JavaLineBreakpointType.class); + } + } + } + if (result.isNull()) { + result.set(JavaMethodBreakpointType.class); + } + } + else if (parent instanceof PsiField) { + if (result.isNull()) { + result.set(JavaFieldBreakpointType.class); + } + } + else { + result.set(JavaLineBreakpointType.class); + } + return true; + } + }); + return result.get() == getClass(); + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaMethodBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaMethodBreakpointType.java new file mode 100644 index 000000000000..94c3c77d80ce --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaMethodBreakpointType.java @@ -0,0 +1,122 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.HelpID; +import com.intellij.icons.AllIcons; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.StringBuilderSpinAllocator; +import com.intellij.xdebugger.breakpoints.XBreakpoint; +import com.intellij.xdebugger.breakpoints.XLineBreakpoint; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.java.debugger.breakpoints.properties.JavaMethodBreakpointProperties; + +import javax.swing.*; + +/** + * @author Eugene Zhuravlev + * Date: Apr 26, 2005 + */ +public class JavaMethodBreakpointType extends JavaLineBreakpointTypeBase<JavaMethodBreakpointProperties> implements JavaBreakpointType { + public JavaMethodBreakpointType() { + super("java-method", DebuggerBundle.message("method.breakpoints.tab.title")); + } + + @NotNull + @Override + public Icon getEnabledIcon() { + return AllIcons.Debugger.Db_method_breakpoint; + } + + @NotNull + @Override + public Icon getDisabledIcon() { + return AllIcons.Debugger.Db_disabled_method_breakpoint; + } + + //@Override + protected String getHelpID() { + return HelpID.METHOD_BREAKPOINTS; + } + + @Override + public boolean isAddBreakpointButtonVisible() { + return false; + } + + //@Override + public String getDisplayName() { + return DebuggerBundle.message("method.breakpoints.tab.title"); + } + + @Override + public String getShortText(XLineBreakpoint<JavaMethodBreakpointProperties> breakpoint) { + return getText(breakpoint); + } + + static String getText(XBreakpoint<JavaMethodBreakpointProperties> breakpoint) { + final StringBuilder buffer = StringBuilderSpinAllocator.alloc(); + try { + //if(isValid()) { + final String className = breakpoint.getProperties().myClassPattern; + final boolean classNameExists = className != null && className.length() > 0; + if (classNameExists) { + buffer.append(className); + } + if(breakpoint.getProperties().myMethodName != null) { + if (classNameExists) { + buffer.append("."); + } + buffer.append(breakpoint.getProperties().myMethodName); + } + //} + //else { + // buffer.append(DebuggerBundle.message("status.breakpoint.invalid")); + //} + return buffer.toString(); + } + finally { + StringBuilderSpinAllocator.dispose(buffer); + } + } + + @Nullable + @Override + public XBreakpointCustomPropertiesPanel createCustomPropertiesPanel() { + return new MethodBreakpointPropertiesPanel(); + } + + @Nullable + @Override + public JavaMethodBreakpointProperties createProperties() { + return new JavaMethodBreakpointProperties(); + } + + @Nullable + @Override + public JavaMethodBreakpointProperties createBreakpointProperties(@NotNull VirtualFile file, int line) { + return new JavaMethodBreakpointProperties(); + } + + @Override + public Breakpoint createJavaBreakpoint(Project project, XBreakpoint breakpoint) { + return new MethodBreakpoint(project, breakpoint); + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaWildcardMethodBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaWildcardMethodBreakpointType.java new file mode 100644 index 000000000000..dd28ee241f1a --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaWildcardMethodBreakpointType.java @@ -0,0 +1,107 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.HelpID; +import com.intellij.icons.AllIcons; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.xdebugger.XDebuggerManager; +import com.intellij.xdebugger.breakpoints.XBreakpoint; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.java.debugger.breakpoints.properties.JavaMethodBreakpointProperties; + +import javax.swing.*; + +/** + * @author Egor + */ +public class JavaWildcardMethodBreakpointType extends JavaBreakpointTypeBase<JavaMethodBreakpointProperties> implements JavaBreakpointType { + public JavaWildcardMethodBreakpointType() { + super("java-wildcard-method", DebuggerBundle.message("method.breakpoints.tab.title")); + } + + @NotNull + @Override + public Icon getEnabledIcon() { + return AllIcons.Debugger.Db_method_breakpoint; + } + + @NotNull + @Override + public Icon getDisabledIcon() { + return AllIcons.Debugger.Db_disabled_method_breakpoint; + } + + //@Override + protected String getHelpID() { + return HelpID.METHOD_BREAKPOINTS; + } + + //@Override + public String getDisplayName() { + return DebuggerBundle.message("method.breakpoints.tab.title"); + } + + @Override + public String getDisplayText(XBreakpoint<JavaMethodBreakpointProperties> breakpoint) { + return JavaMethodBreakpointType.getText(breakpoint); + } + + @Nullable + @Override + public XBreakpointCustomPropertiesPanel<XBreakpoint<JavaMethodBreakpointProperties>> createCustomPropertiesPanel() { + return new MethodBreakpointPropertiesPanel(); + } + + //@Override + //public Key<MethodBreakpoint> getBreakpointCategory() { + // return MethodBreakpoint.CATEGORY; + //} + + @Nullable + @Override + public JavaMethodBreakpointProperties createProperties() { + return new JavaMethodBreakpointProperties(); + } + + @Nullable + @Override + public XBreakpoint<JavaMethodBreakpointProperties> addBreakpoint(final Project project, JComponent parentComponent) { + final AddWildcardBreakpointDialog dialog = new AddWildcardBreakpointDialog(project); + dialog.show(); + if (!dialog.isOK()) { + return null; + } + return ApplicationManager.getApplication().runWriteAction(new Computable<XBreakpoint<JavaMethodBreakpointProperties>>() { + @Override + public XBreakpoint<JavaMethodBreakpointProperties> compute() { + return XDebuggerManager.getInstance(project).getBreakpointManager().addBreakpoint(JavaWildcardMethodBreakpointType.this, new JavaMethodBreakpointProperties( + dialog.getClassPattern(), + dialog.getMethodName())); + } + }); + } + + @Override + public Breakpoint createJavaBreakpoint(Project project, XBreakpoint breakpoint) { + return new WildcardMethodBreakpoint(project, breakpoint); + } +} 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 307b9629b99f..2b3239122373 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 @@ -54,6 +54,7 @@ import com.intellij.util.Processor; import com.intellij.util.StringBuilderSpinAllocator; import com.intellij.util.containers.ContainerUtil; import com.intellij.xdebugger.XDebuggerUtil; +import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.sun.jdi.*; import com.sun.jdi.event.LocatableEvent; import com.sun.jdi.request.BreakpointRequest; @@ -74,12 +75,8 @@ public class LineBreakpoint extends BreakpointWithHighlighter { private String myOwnerMethodName; public static final @NonNls Key<LineBreakpoint> CATEGORY = BreakpointCategory.lookup("line_breakpoints"); - protected LineBreakpoint(Project project) { - super(project); - } - - public LineBreakpoint(Project project, RangeHighlighter highlighter) { - super(project, highlighter); + protected LineBreakpoint(Project project, XBreakpoint xBreakpoint) { + super(project, xBreakpoint); } @Override @@ -95,7 +92,7 @@ public class LineBreakpoint extends BreakpointWithHighlighter { @Override protected Icon getSetIcon(boolean isMuted) { - if (REMOVE_AFTER_HIT) { + if (isRemoveAfterHit()) { return isMuted ? AllIcons.Debugger.Db_muted_temporary_breakpoint : AllIcons.Debugger.Db_temporary_breakpoint; } return isMuted? AllIcons.Debugger.Db_muted_breakpoint : AllIcons.Debugger.Db_set_breakpoint; @@ -108,7 +105,7 @@ public class LineBreakpoint extends BreakpointWithHighlighter { @Override protected Icon getVerifiedIcon(boolean isMuted) { - if (REMOVE_AFTER_HIT) { + if (isRemoveAfterHit()) { return isMuted ? AllIcons.Debugger.Db_muted_temporary_breakpoint : AllIcons.Debugger.Db_temporary_breakpoint; } return isMuted? AllIcons.Debugger.Db_muted_verified_breakpoint : AllIcons.Debugger.Db_verified_breakpoint; @@ -349,9 +346,8 @@ public class LineBreakpoint extends BreakpointWithHighlighter { } private String getDisplayInfoInternal(boolean showPackageInfo, int totalTextLength) { - final RangeHighlighter highlighter = getHighlighter(); - if(highlighter != null && highlighter.isValid() && isValid()) { - final int lineNumber = (highlighter.getDocument().getLineNumber(highlighter.getStartOffset()) + 1); + if(isValid()) { + final int lineNumber = getSourcePosition().getLine() + 1; String className = getClassName(); final boolean hasClassInfo = className != null && className.length() > 0; final String methodName = getMethodName(); @@ -471,24 +467,19 @@ public class LineBreakpoint extends BreakpointWithHighlighter { return ContextUtil.getContextElement(getSourcePosition()); } - public static LineBreakpoint create(@NotNull Project project, @NotNull Document document, int lineIndex) { - final RangeHighlighter highlighter = createHighlighter(project, document, lineIndex); - if (highlighter == null) { - return null; - } - - LineBreakpoint breakpoint = new LineBreakpoint(project, highlighter); + public static LineBreakpoint create(@NotNull Project project, XBreakpoint xBreakpoint) { + LineBreakpoint breakpoint = new LineBreakpoint(project, xBreakpoint); return (LineBreakpoint)breakpoint.init(); } - @Override - public boolean canMoveTo(SourcePosition position) { - if (!super.canMoveTo(position)) { - return false; - } - final Document document = PsiDocumentManager.getInstance(getProject()).getDocument(position.getFile()); - return canAddLineBreakpoint(myProject, document, position.getLine()); - } + //@Override + //public boolean canMoveTo(SourcePosition position) { + // if (!super.canMoveTo(position)) { + // return false; + // } + // final Document document = PsiDocumentManager.getInstance(getProject()).getDocument(position.getFile()); + // return canAddLineBreakpoint(myProject, document, position.getLine()); + //} public static boolean canAddLineBreakpoint(Project project, final Document document, final int lineIndex) { if (lineIndex < 0 || lineIndex >= document.getLineCount()) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointFactory.java deleted file mode 100644 index 0042074dc798..000000000000 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointFactory.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.debugger.ui.breakpoints; - -import com.intellij.debugger.DebuggerBundle; -import com.intellij.debugger.HelpID; -import com.intellij.icons.AllIcons; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Key; -import org.jdom.Element; - -import javax.swing.*; - -/** - * @author Eugene Zhuravlev - * Date: Apr 26, 2005 - */ -public class LineBreakpointFactory extends BreakpointFactory { - @Override - public Breakpoint createBreakpoint(Project project, final Element element) { - return new LineBreakpoint(project); - } - - @Override - public Icon getIcon() { - return AllIcons.Debugger.Db_set_breakpoint; - } - - @Override - public Icon getDisabledIcon() { - return AllIcons.Debugger.Db_disabled_breakpoint; - } - - @Override - protected String getHelpID() { - return HelpID.LINE_BREAKPOINTS; - } - - @Override - public String getDisplayName() { - return DebuggerBundle.message("line.breakpoints.tab.title"); - } - - @Override - public BreakpointPropertiesPanel createBreakpointPropertiesPanel(Project project, boolean compact) { - return new LineBreakpointPropertiesPanel(project, compact); - } - - @Override - public Key<LineBreakpoint> getBreakpointCategory() { - return LineBreakpoint.CATEGORY; - } -} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java index 90a839d425d4..be10d56113f8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java @@ -38,10 +38,13 @@ import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizerUtil; import com.intellij.openapi.util.Key; import com.intellij.psi.*; import com.intellij.util.StringBuilderSpinAllocator; import com.intellij.util.text.CharArrayUtil; +import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.sun.jdi.AbsentInformationException; import com.sun.jdi.Location; import com.sun.jdi.Method; @@ -52,31 +55,29 @@ import com.sun.jdi.event.MethodExitEvent; import com.sun.jdi.request.EventRequest; import com.sun.jdi.request.MethodEntryRequest; import com.sun.jdi.request.MethodExitRequest; +import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.java.debugger.breakpoints.properties.JavaMethodBreakpointProperties; import javax.swing.*; import java.util.Iterator; import java.util.Set; -public class MethodBreakpoint extends BreakpointWithHighlighter { +public class MethodBreakpoint extends BreakpointWithHighlighter<JavaMethodBreakpointProperties> { private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.MethodBreakpoint"); - public boolean WATCH_ENTRY = true; - public boolean WATCH_EXIT = true; - - @Nullable private String myMethodName; @Nullable private JVMName mySignature; private boolean myIsStatic; public static final @NonNls Key<MethodBreakpoint> CATEGORY = BreakpointCategory.lookup("method_breakpoints"); - protected MethodBreakpoint(@NotNull Project project) { - super(project); + protected MethodBreakpoint(@NotNull Project project, XBreakpoint breakpoint) { + super(project, breakpoint); } private MethodBreakpoint(@NotNull Project project, @NotNull RangeHighlighter highlighter) { - super(project, highlighter); + super(project, highlighter, null); } public boolean isStatic() { @@ -104,21 +105,25 @@ public class MethodBreakpoint extends BreakpointWithHighlighter { } public boolean isValid() { - return super.isValid() && myMethodName != null; + return super.isValid() && getMethodName() != null; } protected void reload(@NotNull PsiFile psiFile) { - myMethodName = null; + setMethodName(null); mySignature = null; MethodDescriptor descriptor = getMethodDescriptor(myProject, psiFile, getSourcePosition()); if (descriptor != null) { - myMethodName = descriptor.methodName; + setMethodName(descriptor.methodName); mySignature = descriptor.methodSignature; myIsStatic = descriptor.isStatic; } + PsiClass psiClass = getPsiClass(); + if (psiClass != null) { + getProperties().myClassPattern = psiClass.getQualifiedName(); + } if (myIsStatic) { - INSTANCE_FILTERS_ENABLED = false; + setInstanceFiltersEnabled(false); } } @@ -130,7 +135,7 @@ public class MethodBreakpoint extends BreakpointWithHighlighter { String signature = method.signature(); String name = method.name(); - if (myMethodName.equals(name) && mySignature.getName(debugProcess).equals(signature)) { + if (getMethodName().equals(name) && mySignature.getName(debugProcess).equals(signature)) { hasMethod = true; break; } @@ -144,7 +149,7 @@ public class MethodBreakpoint extends BreakpointWithHighlighter { } RequestManagerImpl requestManager = debugProcess.getRequestsManager(); - if (WATCH_ENTRY) { + if (isWatchEntry()) { MethodEntryRequest entryRequest = (MethodEntryRequest)findRequest(debugProcess, MethodEntryRequest.class); if (entryRequest == null) { entryRequest = requestManager.createMethodEntryRequest(this); @@ -157,7 +162,7 @@ public class MethodBreakpoint extends BreakpointWithHighlighter { entryRequest.addClassFilter(classType); debugProcess.getRequestsManager().enableRequest(entryRequest); } - if (WATCH_EXIT) { + if (isWatchExit()) { MethodExitRequest exitRequest = (MethodExitRequest)findRequest(debugProcess, MethodExitRequest.class); if (exitRequest == null) { exitRequest = requestManager.createMethodExitRequest(this); @@ -256,11 +261,11 @@ public class MethodBreakpoint extends BreakpointWithHighlighter { if (classNameExists) { buffer.append(className); } - if(myMethodName != null) { + if(getMethodName() != null) { if (classNameExists) { buffer.append("."); } - buffer.append(myMethodName); + buffer.append(getMethodName()); } } else { @@ -281,16 +286,16 @@ public class MethodBreakpoint extends BreakpointWithHighlighter { } public boolean matchesEvent(@NotNull final LocatableEvent event, final DebugProcessImpl process) throws EvaluateException { - if (myMethodName == null || mySignature == null) { + if (getMethodName() == null || mySignature == null) { return false; } final Method method = event.location().method(); - return method != null && method.name().equals(myMethodName) && method.signature().equals(mySignature.getName(process)); + return method != null && method.name().equals(getMethodName()) && method.signature().equals(mySignature.getName(process)); } @Nullable - public static MethodBreakpoint create(@NotNull Project project, @NotNull Document document, int lineIndex) { - final MethodBreakpoint breakpoint = new MethodBreakpoint(project, createHighlighter(project, document, lineIndex)); + public static MethodBreakpoint create(@NotNull Project project, XBreakpoint xBreakpoint) { + final MethodBreakpoint breakpoint = new MethodBreakpoint(project, xBreakpoint); return (MethodBreakpoint)breakpoint.init(); } @@ -362,6 +367,19 @@ public class MethodBreakpoint extends BreakpointWithHighlighter { return null; } + @Override + public void readExternal(@NotNull Element breakpointNode) throws InvalidDataException { + super.readExternal(breakpointNode); + try { + getProperties().WATCH_ENTRY = Boolean.valueOf(JDOMExternalizerUtil.readField(breakpointNode, "WATCH_ENTRY")); + } catch (Exception e) { + } + try { + getProperties().WATCH_EXIT = Boolean.valueOf(JDOMExternalizerUtil.readField(breakpointNode, "WATCH_EXIT")); + } catch (Exception e) { + } + } + public String toString() { return getDescription(); } @@ -376,6 +394,23 @@ public class MethodBreakpoint extends BreakpointWithHighlighter { return false; } + private boolean isWatchEntry() { + return getProperties().WATCH_ENTRY; + } + + private boolean isWatchExit() { + return getProperties().WATCH_EXIT; + } + + @Nullable + private String getMethodName() { + return getProperties().myMethodName; + } + + private void setMethodName(@Nullable String methodName) { + getProperties().myMethodName = methodName; + } + private static final class MethodDescriptor { String methodName; JVMName methodSignature; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointFactory.java deleted file mode 100644 index a08e2a123ae6..000000000000 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointFactory.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.debugger.ui.breakpoints; - -import com.intellij.debugger.DebuggerBundle; -import com.intellij.debugger.DebuggerManagerEx; -import com.intellij.debugger.HelpID; -import com.intellij.icons.AllIcons; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Key; -import org.jdom.Element; - -import javax.swing.*; - -/** - * @author Eugene Zhuravlev - * Date: Apr 26, 2005 - */ -public class MethodBreakpointFactory extends BreakpointFactory{ - @Override - public Breakpoint createBreakpoint(Project project, final Element element) { - return element.getAttributeValue(WildcardMethodBreakpoint.JDOM_LABEL) != null? new WildcardMethodBreakpoint(project) : new MethodBreakpoint(project); - } - - @Override - public Icon getIcon() { - return AllIcons.Debugger.Db_method_breakpoint; - } - - @Override - public Icon getDisabledIcon() { - return AllIcons.Debugger.Db_disabled_method_breakpoint; - } - - @Override - protected String getHelpID() { - return HelpID.METHOD_BREAKPOINTS; - } - - @Override - public String getDisplayName() { - return DebuggerBundle.message("method.breakpoints.tab.title"); - } - - @Override - public BreakpointPropertiesPanel createBreakpointPropertiesPanel(Project project, boolean compact) { - return new MethodBreakpointPropertiesPanel(project, compact); - } - - @Override - public Key<MethodBreakpoint> getBreakpointCategory() { - return MethodBreakpoint.CATEGORY; - } - - @Override - public boolean canAddBreakpoints() { - return true; - } - - @Override - public WildcardMethodBreakpoint addBreakpoint(Project project) { - AddWildcardBreakpointDialog dialog = new AddWildcardBreakpointDialog(project); - dialog.show(); - WildcardMethodBreakpoint methodBreakpoint; - methodBreakpoint = !dialog.isOK() - ? null - : DebuggerManagerEx.getInstanceEx(project).getBreakpointManager() - .addMethodBreakpoint(dialog.getClassPattern(), dialog.getMethodName()); - return methodBreakpoint; - } -} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java index c50b6995d038..bf7419264105 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java @@ -21,24 +21,30 @@ package com.intellij.debugger.ui.breakpoints; import com.intellij.debugger.DebuggerBundle; -import com.intellij.openapi.project.Project; import com.intellij.ui.IdeBorderFactory; import com.intellij.util.ui.DialogUtil; +import com.intellij.xdebugger.breakpoints.XBreakpoint; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.java.debugger.breakpoints.properties.JavaMethodBreakpointProperties; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -public class MethodBreakpointPropertiesPanel extends BreakpointPropertiesPanel { +public class MethodBreakpointPropertiesPanel extends XBreakpointCustomPropertiesPanel<XBreakpoint<JavaMethodBreakpointProperties>> { private JCheckBox myWatchEntryCheckBox; private JCheckBox myWatchExitCheckBox; - public MethodBreakpointPropertiesPanel(final Project project, boolean compact) { - super(project, MethodBreakpoint.CATEGORY, compact); - } + //public MethodBreakpointPropertiesPanel(final Project project, boolean compact) { + // super(project, MethodBreakpoint.CATEGORY, compact); + //} + - protected JComponent createSpecialBox() { + @NotNull + @Override + public JComponent getComponent() { JPanel _panel, _panel0; myWatchEntryCheckBox = new JCheckBox(DebuggerBundle.message("label.method.breakpoint.properties.panel.method.entry")); @@ -86,31 +92,15 @@ public class MethodBreakpointPropertiesPanel extends BreakpointPropertiesPanel { return _panel; } - public void initFrom(Breakpoint breakpoint, boolean moreOptionsVisible) { - super.initFrom(breakpoint, moreOptionsVisible); - if (breakpoint instanceof MethodBreakpoint) { - MethodBreakpoint methodBreakpoint = (MethodBreakpoint)breakpoint; - myWatchEntryCheckBox.setSelected(methodBreakpoint.WATCH_ENTRY); - myWatchExitCheckBox.setSelected(methodBreakpoint.WATCH_EXIT); - } - else if (breakpoint instanceof WildcardMethodBreakpoint){ - final WildcardMethodBreakpoint methodBreakpoint = ((WildcardMethodBreakpoint)breakpoint); - myWatchEntryCheckBox.setSelected(methodBreakpoint.WATCH_ENTRY); - myWatchExitCheckBox.setSelected(methodBreakpoint.WATCH_EXIT); - } + @Override + public void loadFrom(@NotNull XBreakpoint<JavaMethodBreakpointProperties> breakpoint) { + myWatchEntryCheckBox.setSelected(breakpoint.getProperties().WATCH_ENTRY); + myWatchExitCheckBox.setSelected(breakpoint.getProperties().WATCH_EXIT); } - public void saveTo(Breakpoint breakpoint) { - if (breakpoint instanceof MethodBreakpoint) { - MethodBreakpoint methodBreakpoint = (MethodBreakpoint)breakpoint; - methodBreakpoint.WATCH_ENTRY = myWatchEntryCheckBox.isSelected(); - methodBreakpoint.WATCH_EXIT = myWatchExitCheckBox.isSelected(); - } - else if (breakpoint instanceof WildcardMethodBreakpoint){ - final WildcardMethodBreakpoint methodBreakpoint = ((WildcardMethodBreakpoint)breakpoint); - methodBreakpoint.WATCH_ENTRY = myWatchEntryCheckBox.isSelected(); - methodBreakpoint.WATCH_EXIT = myWatchExitCheckBox.isSelected(); - } - super.saveTo(breakpoint); + @Override + public void saveTo(@NotNull XBreakpoint<JavaMethodBreakpointProperties> breakpoint) { + breakpoint.getProperties().WATCH_ENTRY = myWatchEntryCheckBox.isSelected(); + breakpoint.getProperties().WATCH_EXIT = myWatchExitCheckBox.isSelected(); } }
\ No newline at end of file diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/RunToCursorBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/RunToCursorBreakpoint.java index 82f617a14f6b..19a187da03c4 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/RunToCursorBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/RunToCursorBreakpoint.java @@ -18,10 +18,11 @@ package com.intellij.debugger.ui.breakpoints; import com.intellij.debugger.SourcePosition; import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,18 +32,11 @@ import org.jetbrains.annotations.Nullable; */ public class RunToCursorBreakpoint extends LineBreakpoint { private final boolean myRestoreBreakpoints; - @Nullable private final SourcePosition myCustomPosition; - - protected RunToCursorBreakpoint(@NotNull Project project, @NotNull RangeHighlighter highlighter, boolean restoreBreakpoints) { - super(project, highlighter); - setVisible(false); - myRestoreBreakpoints = restoreBreakpoints; - myCustomPosition = null; - } + private String mySuspendPolicy; protected RunToCursorBreakpoint(@NotNull Project project, @NotNull SourcePosition pos, boolean restoreBreakpoints) { - super(project); + super(project, null); myCustomPosition = pos; setVisible(false); myRestoreBreakpoints = restoreBreakpoints; @@ -50,7 +44,51 @@ public class RunToCursorBreakpoint extends LineBreakpoint { @Override public SourcePosition getSourcePosition() { - return myCustomPosition != null ? myCustomPosition : super.getSourcePosition(); + return myCustomPosition; + } + + @Override + public void reload() { + } + + @Override + public String getSuspendPolicy() { + return mySuspendPolicy; + } + + public void setSuspendPolicy(String policy) { + mySuspendPolicy = policy; + } + + protected boolean isLogEnabled() { + return false; + } + + @Override + protected boolean isLogExpressionEnabled() { + return false; + } + + @Override + public boolean isEnabled() { + return true; + } + + public boolean isCountFilterEnabled() { + return false; + } + + public boolean isClassFiltersEnabled() { + return false; + } + + public boolean isInstanceFiltersEnabled() { + return false; + } + + @Override + protected boolean isConditionEnabled() { + return false; } public boolean isRestoreBreakpoints() { @@ -63,6 +101,11 @@ public class RunToCursorBreakpoint extends LineBreakpoint { } @Override + public boolean isValid() { + return true; + } + + @Override protected boolean isMuted(@NotNull final DebugProcessImpl debugProcess) { return false; // always enabled } @@ -74,17 +117,9 @@ public class RunToCursorBreakpoint extends LineBreakpoint { return null; } - final RangeHighlighter highlighter = createHighlighter(project, document, lineIndex); - if (highlighter == null) { - return null; - } - - final RunToCursorBreakpoint breakpoint = new RunToCursorBreakpoint(project, highlighter, restoreBreakpoints); - final RangeHighlighter h = breakpoint.getHighlighter(); - if (h != null) { - h.dispose(); - } + PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile); + SourcePosition pos = SourcePosition.createFromLine(psiFile, lineIndex); - return (RunToCursorBreakpoint)breakpoint.init(); + return new RunToCursorBreakpoint(project, pos, restoreBreakpoints); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StepIntoBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StepIntoBreakpoint.java index 6e39e5ac1d29..af7d6755523a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StepIntoBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StepIntoBreakpoint.java @@ -153,7 +153,7 @@ public class StepIntoBreakpoint extends RunToCursorBreakpoint { if (pos != null) { final StepIntoBreakpoint breakpoint = new StepIntoBreakpoint(project, pos, filter); breakpoint.init(); - breakpoint.LOG_ENABLED = false; + breakpoint.setLogEnabled(false); return breakpoint; } return null; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java index f6c0dc3c3ab2..295fddbaf187 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java @@ -23,15 +23,20 @@ import com.intellij.debugger.engine.DebuggerManagerThreadImpl; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; import com.intellij.debugger.engine.requests.RequestManagerImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.icons.AllIcons; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizerUtil; import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.WriteExternalException; import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.StringBuilderSpinAllocator; +import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.sun.jdi.AbsentInformationException; import com.sun.jdi.Location; import com.sun.jdi.Method; @@ -45,37 +50,33 @@ import com.sun.jdi.request.MethodExitRequest; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.java.debugger.breakpoints.properties.JavaMethodBreakpointProperties; import javax.swing.*; import java.util.Iterator; import java.util.Set; -public class WildcardMethodBreakpoint extends Breakpoint { +public class WildcardMethodBreakpoint extends Breakpoint<JavaMethodBreakpointProperties> { private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.ExceptionBreakpoint"); - public boolean WATCH_ENTRY = true; - public boolean WATCH_EXIT = true; - private String myClassPattern; - private String myMethodName; - public static final String JDOM_LABEL = "wildcard_breakpoint"; - public WildcardMethodBreakpoint(Project project) { - super(project); + public WildcardMethodBreakpoint(Project project, XBreakpoint breakpoint) { + super(project, breakpoint); } public Key<MethodBreakpoint> getCategory() { return MethodBreakpoint.CATEGORY; } - protected WildcardMethodBreakpoint(Project project, @NotNull String classPattern, @NotNull String methodName) { - super(project); - myClassPattern = classPattern; - myMethodName = methodName; + protected WildcardMethodBreakpoint(Project project, @NotNull String classPattern, @NotNull String methodName, XBreakpoint breakpoint) { + super(project, breakpoint); + setClassPattern(classPattern); + setMethodName(methodName); } public String getClassName() { - return myClassPattern; + return getClassPattern(); } public @Nullable String getShortClassName() { @@ -83,11 +84,15 @@ public class WildcardMethodBreakpoint extends Breakpoint { } public String getMethodName() { - return myMethodName; + return getProperties().myMethodName; } public PsiClass getPsiClass() { - return null; + return PsiDocumentManager.getInstance(myProject).commitAndRunReadAction(new Computable<PsiClass>() { + public PsiClass compute() { + return getClassName() != null ? DebuggerUtilsEx.findClass(getClassName(), myProject, GlobalSearchScope.allScope(myProject)) : null; + } + }); } public String getDisplayName() { @@ -96,9 +101,9 @@ public class WildcardMethodBreakpoint extends Breakpoint { } final StringBuilder buffer = StringBuilderSpinAllocator.alloc(); try { - buffer.append(myClassPattern); + buffer.append(getClassPattern()); buffer.append("."); - buffer.append(myMethodName); + buffer.append(getMethodName()); buffer.append("()"); return buffer.toString(); } @@ -108,7 +113,7 @@ public class WildcardMethodBreakpoint extends Breakpoint { } public Icon getIcon() { - if (!ENABLED) { + if (!isEnabled()) { final Breakpoint master = DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().findMasterBreakpoint(this); return master == null? AllIcons.Debugger.Db_disabled_method_breakpoint : AllIcons.Debugger.Db_dep_method_breakpoint; } @@ -124,12 +129,12 @@ public class WildcardMethodBreakpoint extends Breakpoint { public void createRequest(DebugProcessImpl debugProcess) { DebuggerManagerThreadImpl.assertIsManagerThread(); - if (!ENABLED || !debugProcess.isAttached() || debugProcess.areBreakpointsMuted() || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) { + if (!isEnabled() || !debugProcess.isAttached() || debugProcess.areBreakpointsMuted() || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) { return; } try { RequestManagerImpl requestManager = debugProcess.getRequestsManager(); - if (WATCH_ENTRY) { + if (isWatchEntry()) { MethodEntryRequest entryRequest = (MethodEntryRequest)findRequest(debugProcess, MethodEntryRequest.class); if (entryRequest == null) { entryRequest = requestManager.createMethodEntryRequest(this); @@ -137,10 +142,10 @@ public class WildcardMethodBreakpoint extends Breakpoint { else { entryRequest.disable(); } - entryRequest.addClassFilter(myClassPattern); + entryRequest.addClassFilter(getClassPattern()); debugProcess.getRequestsManager().enableRequest(entryRequest); } - if (WATCH_EXIT) { + if (isWatchExit()) { MethodExitRequest exitRequest = (MethodExitRequest)findRequest(debugProcess, MethodExitRequest.class); if (exitRequest == null) { exitRequest = requestManager.createMethodExitRequest(this); @@ -148,7 +153,7 @@ public class WildcardMethodBreakpoint extends Breakpoint { else { exitRequest.disable(); } - exitRequest.addClassFilter(myClassPattern); + exitRequest.addClassFilter(getClassPattern()); debugProcess.getRequestsManager().enableRequest(exitRequest); } } @@ -212,19 +217,19 @@ public class WildcardMethodBreakpoint extends Breakpoint { } public boolean isValid() { - return myClassPattern != null && myMethodName != null; + return getClassPattern() != null && getMethodName() != null; } - @SuppressWarnings({"HardCodedStringLiteral"}) public void writeExternal(Element parentNode) throws WriteExternalException { - super.writeExternal(parentNode); - parentNode.setAttribute(JDOM_LABEL, "true"); - if (myClassPattern != null) { - parentNode.setAttribute("class_name", myClassPattern); - } - if (myMethodName != null) { - parentNode.setAttribute("method_name", myMethodName); - } - } + //@SuppressWarnings({"HardCodedStringLiteral"}) public void writeExternal(Element parentNode) throws WriteExternalException { + // super.writeExternal(parentNode); + // parentNode.setAttribute(JDOM_LABEL, "true"); + // if (getClassPattern() != null) { + // parentNode.setAttribute("class_name", getClassPattern()); + // } + // if (getMethodName() != null) { + // parentNode.setAttribute("method_name", getMethodName()); + // } + //} public PsiElement getEvaluationElement() { return null; @@ -235,11 +240,20 @@ public class WildcardMethodBreakpoint extends Breakpoint { //noinspection HardCodedStringLiteral String className = parentNode.getAttributeValue("class_name"); - myClassPattern = className; + setClassPattern(className); //noinspection HardCodedStringLiteral String methodName = parentNode.getAttributeValue("method_name"); - myMethodName = methodName; + setMethodName(methodName); + + try { + getProperties().WATCH_ENTRY = Boolean.valueOf(JDOMExternalizerUtil.readField(parentNode, "WATCH_ENTRY")); + } catch (Exception e) { + } + try { + getProperties().WATCH_EXIT = Boolean.valueOf(JDOMExternalizerUtil.readField(parentNode, "WATCH_EXIT")); + } catch (Exception e) { + } if(className == null || methodName == null) { throw new InvalidDataException(); @@ -248,10 +262,38 @@ public class WildcardMethodBreakpoint extends Breakpoint { public boolean matchesEvent(final LocatableEvent event){ final Method method = event.location().method(); - return method != null && myMethodName.equals(method.name()); + return method != null && getMethodName().equals(method.name()); + } + + public static WildcardMethodBreakpoint create(Project project, final String classPattern, final String methodName, XBreakpoint xBreakpoint) { + return new WildcardMethodBreakpoint(project, classPattern, methodName, xBreakpoint); + } + + private boolean isWatchEntry() { + return getProperties().WATCH_ENTRY; + } + + private void setWatchEntry(boolean WATCH_ENTRY) { + getProperties().WATCH_ENTRY = WATCH_ENTRY; + } + + private boolean isWatchExit() { + return getProperties().WATCH_EXIT; + } + + private void setWatchExit(boolean WATCH_EXIT) { + getProperties().WATCH_EXIT = WATCH_EXIT; + } + + private String getClassPattern() { + return getProperties().myClassPattern; + } + + private void setClassPattern(String classPattern) { + getProperties().myClassPattern = classPattern; } - public static WildcardMethodBreakpoint create(Project project, final String classPattern, final String methodName) { - return new WildcardMethodBreakpoint(project, classPattern, methodName); + private void setMethodName(String methodName) { + getProperties().myMethodName = methodName; } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java index 25cc97222726..c04f1bf63d67 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java @@ -93,7 +93,7 @@ public abstract class DebuggerTreePanel extends UpdatableDebuggerView implements getTree().rebuild(context); } } - catch (VMDisconnectedException e) { + catch (VMDisconnectedException ignored) { // ignored } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java index 30306a49ae84..788cb17b477e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java @@ -83,11 +83,13 @@ public class FrameVariablesTree extends DebuggerTree { } } + @Override protected void build(DebuggerContextImpl context) { myAnyNewLocals = false; buildWhenPaused(context, new RefreshFrameTreeCommand(context)); } + @Override public void restoreNodeState(DebuggerTreeNodeImpl node) { if (myAnyNewLocals) { final NodeDescriptorImpl descriptor = node.getDescriptor(); @@ -107,6 +109,7 @@ public class FrameVariablesTree extends DebuggerTree { } + @Override protected DebuggerCommandImpl getBuildNodeCommand(final DebuggerTreeNodeImpl node) { if (node.getDescriptor() instanceof StackFrameDescriptorImpl) { return new BuildFrameTreeVariablesCommand(node); @@ -119,6 +122,7 @@ public class FrameVariablesTree extends DebuggerTree { super(stackNode); } + @Override protected void buildVariables(final StackFrameDescriptorImpl stackDescriptor, final EvaluationContextImpl evaluationContext) throws EvaluateException { final DebuggerContextImpl debuggerContext = getDebuggerContext(); final SourcePosition sourcePosition = debuggerContext.getSourcePosition(); @@ -135,6 +139,7 @@ public class FrameVariablesTree extends DebuggerTree { final EvaluationContextImpl evalContext = debuggerContext.createEvaluationContext(); final Pair<Set<String>, Set<TextWithImports>> usedVars = ApplicationManager.getApplication().runReadAction(new Computable<Pair<Set<String>, Set<TextWithImports>>>() { + @Override public Pair<Set<String>, Set<TextWithImports>> compute() { return findReferencedVars(visibleVariables.keySet(), sourcePosition, evalContext); } @@ -396,6 +401,7 @@ public class FrameVariablesTree extends DebuggerTree { super(context); } + @Override public void contextAction() throws Exception { DebuggerTreeNodeImpl rootNode; @@ -433,7 +439,7 @@ public class FrameVariablesTree extends DebuggerTree { rootNode.add(MessageDescriptor.THREAD_IS_RUNNING); } } - catch (ObjectCollectedException e) { + catch (ObjectCollectedException ignored) { rootNode.add(new MessageDescriptor(DebuggerBundle.message("label.thread.node.thread.collected", currentThread.name()))); } } @@ -448,12 +454,14 @@ public class FrameVariablesTree extends DebuggerTree { final DebuggerTreeNodeImpl rootNode1 = rootNode; DebuggerInvocationUtil.swingInvokeLater(getProject(), new Runnable() { + @Override public void run() { getMutableModel().setRoot(rootNode1); treeChanged(); final TreeModel model = getModel(); model.addTreeModelListener(new TreeModelAdapter() { + @Override public void treeStructureChanged(TreeModelEvent e) { final Object[] path = e.getPath(); if (path.length > 0 && path[path.length - 1] == rootNode1) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesList.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesList.java index 9967b70eb485..d0d25f1808b5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesList.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesList.java @@ -35,15 +35,18 @@ public class FramesList extends DebuggerFramesList { doInit(); } + @Override protected FramesListRenderer createListRenderer() { return new FramesListRenderer(); } + @Override protected void onFrameChanged(final Object selectedValue) { final StackFrameDescriptorImpl descriptor = selectedValue instanceof StackFrameDescriptorImpl? (StackFrameDescriptorImpl)selectedValue : null; final Method newMethod = descriptor != null? descriptor.getMethod() : null; if (!Comparing.equal(mySelectedMethod, newMethod)) { SwingUtilities.invokeLater(new Runnable() { + @Override public void run() { repaint(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesListRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesListRenderer.java index c6e62281b143..c3368cd5c4f9 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesListRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesListRenderer.java @@ -16,14 +16,14 @@ package com.intellij.debugger.ui.impl; import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl; -import com.intellij.ui.JBColor; -import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.util.Comparing; import com.intellij.ui.ColoredListCellRenderer; +import com.intellij.ui.JBColor; import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.ui.UIUtil; +import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; import com.intellij.xdebugger.ui.DebuggerColors; import com.sun.jdi.Method; @@ -38,6 +38,7 @@ class FramesListRenderer extends ColoredListCellRenderer { myColorScheme = EditorColorsManager.getInstance().getGlobalScheme(); } + @Override protected void customizeCellRenderer(final JList list, final Object item, final int index, final boolean selected, final boolean hasFocus) { if (!(item instanceof StackFrameDescriptorImpl)) { append(item.toString(), SimpleTextAttributes.GRAYED_ATTRIBUTES); 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 4b3f145995b2..e059e789254b 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 @@ -59,10 +59,12 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes setLvalue(!field.isFinal()); } + @Override public Field getField() { return myField; } + @Override public ObjectReference getObject() { return myObject; } @@ -131,6 +133,7 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes } } + @Override public void setAncestor(NodeDescriptor oldDescriptor) { super.setAncestor(oldDescriptor); final Boolean isPrimitive = ((FieldDescriptorImpl)oldDescriptor).myIsPrimitive; @@ -141,6 +144,7 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes } + @Override public boolean isPrimitive() { if (myIsPrimitive == null) { final Value value = getValue(); @@ -154,12 +158,13 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes return myIsPrimitive.booleanValue(); } + @Override public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException { DebuggerManagerThreadImpl.assertIsManagerThread(); try { return (myObject != null) ? myObject.getValue(myField) : myField.declaringType().getValue(myField); } - catch (ObjectCollectedException e) { + catch (ObjectCollectedException ignored) { throw EvaluateExceptionUtil.OBJECT_WAS_COLLECTED; } } @@ -168,6 +173,7 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes return myIsStatic; } + @Override public String getName() { final String fieldName = myField.name(); if (isOuterLocalVariableValue() && NodeRendererSettings.getInstance().getClassRenderer().SHOW_VAL_FIELDS_AS_LOCAL_VARIABLES) { @@ -180,11 +186,12 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes try { return DebuggerUtils.isSynthetic(myField) && myField.name().startsWith(OUTER_LOCAL_VAR_FIELD_PREFIX); } - catch (UnsupportedOperationException e) { + catch (UnsupportedOperationException ignored) { return false; } } + @Override public String calcValueName() { final ClassRenderer classRenderer = NodeRendererSettings.getInstance().getClassRenderer(); StringBuilder buf = StringBuilderSpinAllocator.alloc(); @@ -201,6 +208,7 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes } } + @Override public PsiExpression getDescriptorEvaluation(DebuggerContext context) throws EvaluateException { PsiElementFactory elementFactory = JavaPsiFacade.getInstance(context.getProject()).getElementFactory(); String fieldName; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MessageDescriptor.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MessageDescriptor.java index 026f2ad6b4b9..6f2aa4e09f0d 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MessageDescriptor.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MessageDescriptor.java @@ -59,17 +59,21 @@ public class MessageDescriptor extends NodeDescriptorImpl { return myKind; } + @Override public String getLabel() { return myMessage; } + @Override public boolean isExpandable() { return false; } + @Override public void setContext(EvaluationContextImpl context) { } + @Override protected String calcRepresentation(EvaluationContextImpl context, DescriptorLabelListener labelListener) throws EvaluateException { DebuggerManagerThreadImpl.assertIsManagerThread(); return myMessage; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorImpl.java index a009733a39a9..f2f5b1c23283 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorImpl.java @@ -52,15 +52,21 @@ public abstract class NodeDescriptorImpl implements NodeDescriptor { private final List<NodeDescriptorImpl> myChildren = new ArrayList<NodeDescriptorImpl>(); private static final Key<Map<ObjectReference, ValueMarkup>> MARKUP_MAP_KEY = new Key<Map<ObjectReference, ValueMarkup>>("ValueMarkupMap"); + @Override public String getName() { return null; } + @Override public <T> T getUserData(Key<T> key) { - if(myUserData == null) return null; - return (T) myUserData.get(key); + if (myUserData == null) { + return null; + } + //noinspection unchecked + return (T)myUserData.get(key); } + @Override public <T> void putUserData(Key<T> key, T value) { if(myUserData == null) { myUserData = new HashMap<Key, Object>(); @@ -91,12 +97,12 @@ public abstract class NodeDescriptorImpl implements NodeDescriptor { protected abstract String calcRepresentation(EvaluationContextImpl context, DescriptorLabelListener labelListener) throws EvaluateException; - private EvaluateException processException(Exception e) { - if(e instanceof InconsistentDebugInfoException) { + private static EvaluateException processException(Exception e) { + if (e instanceof InconsistentDebugInfoException) { return new EvaluateException(DebuggerBundle.message("error.inconsistent.debug.info"), null); } - else if(e instanceof InvalidStackFrameException) { + else if (e instanceof InvalidStackFrameException) { return new EvaluateException(DebuggerBundle.message("error.invalid.stackframe"), null); } else { @@ -104,6 +110,7 @@ public abstract class NodeDescriptorImpl implements NodeDescriptor { } } + @Override public void displayAs(NodeDescriptor descriptor) { if (descriptor instanceof NodeDescriptorImpl) { final NodeDescriptorImpl that = (NodeDescriptorImpl)descriptor; @@ -122,6 +129,7 @@ public abstract class NodeDescriptorImpl implements NodeDescriptor { return myEvaluateException; } + @Override public String getLabel() { return myLabel; } @@ -149,6 +157,7 @@ public abstract class NodeDescriptorImpl implements NodeDescriptor { return myChildren; } + @Override public void setAncestor(NodeDescriptor oldDescriptor) { displayAs(oldDescriptor); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java index 41a5384ae19b..8e11e545dcd0 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java @@ -34,6 +34,8 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.ui.FileColorManager; import com.intellij.util.StringBuilderSpinAllocator; +import com.intellij.util.ui.TextTransferable; +import com.intellij.xdebugger.frame.XStackFrame; import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; import com.sun.jdi.*; import org.jetbrains.annotations.Nullable; @@ -50,6 +52,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac private int myUiIndex; private String myName = null; private Location myLocation; + private final XStackFrame myXStackFrame; private MethodsTracker.MethodOccurrence myMethodOccurrence; private boolean myIsSynthetic; private boolean myIsInLibraryContent; @@ -67,6 +70,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac myMethodOccurrence = tracker.getMethodOccurrence(myLocation.method()); myIsSynthetic = DebuggerUtils.isSynthetic(myMethodOccurrence.getMethod()); ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override public void run() { final SourcePosition position = ContextUtil.getSourcePosition(StackFrameDescriptorImpl.this); final PsiFile file = position != null? position.getFile() : null; @@ -83,7 +87,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac } }); } - catch(InternalException e) { + catch (InternalException e) { LOG.info(e); myLocation = null; myMethodOccurrence = tracker.getMethodOccurrence(null); @@ -97,16 +101,20 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac myIsSynthetic = false; myIsInLibraryContent = false; } + + myXStackFrame = myLocation == null ? null : getDebugProcess().getPositionManager().createStackFrame(myLocation); } public int getUiIndex() { return myUiIndex; } + @Override public StackFrameProxyImpl getFrameProxy() { return myFrame; } + @Override public DebugProcess getDebugProcess() { return myFrame.getVirtualMachine().getDebugProcess(); } @@ -140,12 +148,21 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac return null; } + @Override public String getName() { return myName; } + @Override protected String calcRepresentation(EvaluationContextImpl context, DescriptorLabelListener descriptorLabelListener) throws EvaluateException { DebuggerManagerThreadImpl.assertIsManagerThread(); + + if (myXStackFrame != null) { + TextTransferable.ColoredStringBuilder builder = new TextTransferable.ColoredStringBuilder(); + myXStackFrame.customizePresentation(builder); + return builder.getBuilder().toString(); + } + if (myLocation == null) { return ""; } @@ -159,7 +176,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac label.append("()"); } if (settings.SHOW_LINE_NUMBER) { - String lineNumber = null; + String lineNumber; try { lineNumber = Integer.toString(myLocation.lineNumber()); } @@ -172,7 +189,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac } } if (settings.SHOW_CLASS_NAME) { - String name = null; + String name; try { ReferenceType refType = myLocation.declaringType(); name = refType != null ? refType.name() : null; @@ -206,7 +223,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac label.append(", "); label.append(sourceName); } - catch (AbsentInformationException exception) { + catch (AbsentInformationException ignored) { } } return label.toString(); @@ -220,10 +237,12 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac return getFrameProxy().equals(d.getFrameProxy()); } + @Override public boolean isExpandable() { return true; } + @Override public final void setContext(EvaluationContextImpl context) { myIcon = calcIcon(); } @@ -246,7 +265,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac return AllIcons.Debugger.Db_obsolete; } } - catch (EvaluateException e) { + catch (EvaluateException ignored) { } return AllIcons.Debugger.StackFrame; } diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java b/java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java index 21cdb36a3a4e..5df69039a726 100644 --- a/java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java +++ b/java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java @@ -1,16 +1,28 @@ package org.jetbrains.java.debugger; +import com.intellij.debugger.engine.evaluation.CodeFragmentKind; +import com.intellij.debugger.engine.evaluation.TextWithImports; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.ui.DebuggerExpressionComboBox; import com.intellij.ide.highlighter.JavaFileType; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.JavaCodeFragmentFactory; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.xdebugger.XSourcePosition; +import com.intellij.xdebugger.breakpoints.XBreakpoint; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; +import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProviderBase; +import com.intellij.xdebugger.impl.breakpoints.ui.XDebuggerComboBoxProvider; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class JavaDebuggerEditorsProvider extends XDebuggerEditorsProviderBase { +import javax.swing.*; + +public class JavaDebuggerEditorsProvider extends XDebuggerEditorsProviderBase implements XDebuggerComboBoxProvider { @NotNull @Override public FileType getFileType() { @@ -21,4 +33,77 @@ public class JavaDebuggerEditorsProvider extends XDebuggerEditorsProviderBase { protected PsiFile createExpressionCodeFragment(@NotNull Project project, @NotNull String text, @Nullable PsiElement context, boolean isPhysical) { return JavaCodeFragmentFactory.getInstance(project).createExpressionCodeFragment(text, context, null, isPhysical); } + + @Override + public XBreakpointCustomPropertiesPanel<XBreakpoint<?>> createConditionComboBoxPanel(Project project, + XDebuggerEditorsProvider debuggerEditorsProvider, + String historyId, + XSourcePosition sourcePosition) { + return new ExpressionComboBoxPanel(project, historyId, sourcePosition) { + @Override + public void saveTo(@NotNull XBreakpoint<?> breakpoint) { + TextWithImports text = myComboBox.getText(); + final String condition = !text.getText().isEmpty() ? text.toExternalForm() : null; + breakpoint.setCondition(condition); + if (condition != null) { + myComboBox.addRecent(text); + } + } + + @Override + public void loadFrom(@NotNull XBreakpoint<?> breakpoint) { + myComboBox.setText(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, StringUtil.notNullize(breakpoint.getCondition()))); + } + }; + } + + @Override + public XBreakpointCustomPropertiesPanel<XBreakpoint<?>> createLogExpressionComboBoxPanel(Project project, + XDebuggerEditorsProvider debuggerEditorsProvider, + String historyId, + XSourcePosition sourcePosition) { + return new ExpressionComboBoxPanel(project, historyId, sourcePosition) { + @Override + public void saveTo(@NotNull XBreakpoint<?> breakpoint) { + TextWithImports text = myComboBox.getText(); + breakpoint.setLogExpression(myComboBox.isEnabled() && !text.getText().isEmpty() ? text.toExternalForm() : null); + if (text != null) { + myComboBox.addRecent(text); + } + } + + @Override + public void loadFrom(@NotNull XBreakpoint<?> breakpoint) { + myComboBox.setText(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, StringUtil.notNullize(breakpoint.getLogExpression()))); + } + }; + } + + private abstract class ExpressionComboBoxPanel extends XBreakpointCustomPropertiesPanel<XBreakpoint<?>> { + protected final DebuggerExpressionComboBox myComboBox; + + private ExpressionComboBoxPanel(Project project, + String historyId, + XSourcePosition sourcePosition) { + myComboBox = new DebuggerExpressionComboBox(project, historyId); + if (sourcePosition != null) { + PsiElement element = getContextElement(sourcePosition.getFile(), sourcePosition.getOffset(), project); + myComboBox.setContext(element); + } + else { + myComboBox.setContext(null); + } + } + + @NotNull + @Override + public JComponent getComponent() { + return myComboBox; + } + + @Override + public void dispose() { + myComboBox.dispose(); + } + } }
\ No newline at end of file diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapter.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapter.java deleted file mode 100644 index a6705848a44d..000000000000 --- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapter.java +++ /dev/null @@ -1,157 +0,0 @@ -package org.jetbrains.java.debugger.breakpoints; - -import com.intellij.debugger.engine.evaluation.CodeFragmentKind; -import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; -import com.intellij.debugger.engine.requests.RequestManagerImpl; -import com.intellij.debugger.settings.DebuggerSettings; -import com.intellij.debugger.ui.breakpoints.LineBreakpoint; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.markup.RangeHighlighter; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.xdebugger.breakpoints.XBreakpointProperties; -import com.intellij.xdebugger.breakpoints.XLineBreakpoint; -import com.intellij.xdebugger.impl.breakpoints.XLineBreakpointImpl; -import org.jetbrains.annotations.NotNull; - -import java.util.Arrays; - -public class JavaBreakpointAdapter extends JavaBreakpointAdapterBase { - private static final Key<LineBreakpoint> OLD_JAVA_BREAKPOINT_KEY = Key.create("oldJavaBreakpoint"); - - public JavaBreakpointAdapter(Project project) { - super(project); - } - - @Override - protected void configureCreatedBreakpoint(LineBreakpoint oldBreakpoint, XLineBreakpoint<XBreakpointProperties> breakpoint) { - oldBreakpoint.SUSPEND_POLICY = transformSuspendPolicy(breakpoint); - applyCondition(oldBreakpoint, breakpoint); - applyFilters(oldBreakpoint, breakpoint); - } - - private boolean applyFilters(LineBreakpoint oldBreakpoint, XLineBreakpoint<XBreakpointProperties> breakpoint) { - boolean changed = false; - JavaBreakpointProperties properties = (JavaBreakpointProperties)breakpoint.getProperties(); - - changed |= oldBreakpoint.COUNT_FILTER_ENABLED != properties.COUNT_FILTER_ENABLED; - oldBreakpoint.COUNT_FILTER_ENABLED = properties.COUNT_FILTER_ENABLED; - - changed |= oldBreakpoint.COUNT_FILTER != properties.COUNT_FILTER; - oldBreakpoint.COUNT_FILTER = properties.COUNT_FILTER; - - changed |= oldBreakpoint.CLASS_FILTERS_ENABLED != properties.CLASS_FILTERS_ENABLED; - oldBreakpoint.CLASS_FILTERS_ENABLED = properties.CLASS_FILTERS_ENABLED; - - changed |= !Arrays.equals(oldBreakpoint.getClassFilters(), properties.getClassFilters()); - oldBreakpoint.setClassFilters(properties.getClassFilters()); - - changed |= !Arrays.equals(oldBreakpoint.getClassExclusionFilters(), properties.getClassExclusionFilters()); - oldBreakpoint.setClassExclusionFilters(properties.getClassExclusionFilters()); - - changed |= oldBreakpoint.INSTANCE_FILTERS_ENABLED != properties.INSTANCE_FILTERS_ENABLED; - oldBreakpoint.INSTANCE_FILTERS_ENABLED = properties.INSTANCE_FILTERS_ENABLED; - - changed |= !Arrays.equals(oldBreakpoint.getInstanceFilters(), properties.getInstanceFilters()); - oldBreakpoint.setInstanceFilters(properties.getInstanceFilters()); - - return changed; - } - - private static void applyCondition(LineBreakpoint oldBreakpoint, XLineBreakpoint<XBreakpointProperties> breakpoint) { - if (breakpoint.getCondition() != null) { - oldBreakpoint.CONDITION_ENABLED = true; - oldBreakpoint.setCondition(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, breakpoint.getCondition())); - } - else { - oldBreakpoint.CONDITION_ENABLED = false; - if (!StringUtil.isEmptyOrSpaces(oldBreakpoint.getCondition().getText())) { - oldBreakpoint.setCondition(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, "")); - } - } - } - - @Override - protected void updateBreakpoint(LineBreakpoint jBreakpoint, XLineBreakpoint<XBreakpointProperties> breakpoint) { - boolean changed = false; - if (jBreakpoint.ENABLED != breakpoint.isEnabled()) { - jBreakpoint.ENABLED = breakpoint.isEnabled(); - changed = true; - } - - String suspendPolicy = transformSuspendPolicy(breakpoint); - if (jBreakpoint.SUSPEND_POLICY != suspendPolicy) { - jBreakpoint.SUSPEND_POLICY = suspendPolicy; - changed = true; - } - - if (StringUtil.compare(breakpoint.getCondition(), jBreakpoint.getCondition().getText(), false) != 0) { - applyCondition(jBreakpoint, breakpoint); - changed = true; - } - - if (applyFilters(jBreakpoint, breakpoint)) { - changed = true; - } - - if (jBreakpoint.getSourcePosition().getLine() != breakpoint.getLine()) { - jBreakpoint.reload(); - changed = true; - } - - if (changed) { - RequestManagerImpl.updateRequests(jBreakpoint); - jBreakpoint.updateUI(); - } - } - - @Override - protected LineBreakpoint findBreakpoint(XLineBreakpoint<XBreakpointProperties> breakpoint) { - return OLD_JAVA_BREAKPOINT_KEY.get(breakpoint); - } - - public LineBreakpoint getOrCreate(XLineBreakpoint<XBreakpointProperties> breakpoint) { - LineBreakpoint oldBreakpoint = findBreakpoint(breakpoint); - if (oldBreakpoint == null) { - oldBreakpoint = createBreakpoint(breakpoint); - OLD_JAVA_BREAKPOINT_KEY.set(breakpoint, oldBreakpoint); - } - return oldBreakpoint; - } - - @Override - public void breakpointRemoved(@NotNull XLineBreakpoint<XBreakpointProperties> breakpoint) { - LineBreakpoint jBreakpoint = findBreakpoint(breakpoint); - if (jBreakpoint != null) { - jBreakpoint.delete(); - } - } - - @Override - protected LineBreakpoint doCreateInstance(Project project, Document document, XLineBreakpoint<XBreakpointProperties> breakpoint) { - LineBreakpoint lineBreakpoint = new LineBreakpoint(project, ((XLineBreakpointImpl)breakpoint).getHighlighter()) { - @Override - protected void setEditorFilter(RangeHighlighter highlighter) { - } - }; - - lineBreakpoint.setVisible(false); - lineBreakpoint.init(); - return lineBreakpoint; - } - - private static String transformSuspendPolicy(XLineBreakpoint<XBreakpointProperties> breakpoint) { - switch (breakpoint.getSuspendPolicy()) { - case ALL: - return DebuggerSettings.SUSPEND_ALL; - case THREAD: - return DebuggerSettings.SUSPEND_THREAD; - case NONE: - return DebuggerSettings.SUSPEND_NONE; - - default: - throw new IllegalArgumentException("unknown suspend policy"); - } - } -} diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapterBase.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapterBase.java index 6b249356d340..686de9aad6eb 100644 --- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapterBase.java +++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapterBase.java @@ -56,11 +56,11 @@ public abstract class JavaBreakpointAdapterBase extends XBreakpointAdapter<XLine LineBreakpoint oldBreakpoint = doCreateInstance(project, document, breakpoint); oldBreakpoint.setVisible(false); oldBreakpoint.updateUI(); - oldBreakpoint.ENABLED = breakpoint.isEnabled(); + oldBreakpoint.setEnabled(breakpoint.isEnabled()); return oldBreakpoint; } - protected LineBreakpoint doCreateInstance(Project project, Document document, XLineBreakpoint<XBreakpointProperties> breakpoint) { - return LineBreakpoint.create(project, document, breakpoint.getLine()); + protected LineBreakpoint doCreateInstance(Project project, Document document, XLineBreakpoint<XBreakpointProperties> xBreakpoint) { + return LineBreakpoint.create(project, xBreakpoint); } } diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointPropertiesPanel.form b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.form index db560b3feaeb..39507678f8ff 100644 --- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointPropertiesPanel.form +++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.form @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.java.debugger.breakpoints.JavaBreakpointPropertiesPanel"> +<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.java.debugger.breakpoints.JavaBreakpointFiltersPanel"> <grid id="27dc6" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointPropertiesPanel.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.java index e575973ea0ba..2afcf0fd339f 100644 --- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointPropertiesPanel.java +++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.java @@ -26,11 +26,11 @@ import com.intellij.ui.FieldPanel; import com.intellij.ui.MultiLineTooltipUI; import com.intellij.ui.classFilter.ClassFilter; import com.intellij.xdebugger.XSourcePosition; -import com.intellij.xdebugger.breakpoints.XBreakpointProperties; -import com.intellij.xdebugger.breakpoints.XLineBreakpoint; +import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties; import javax.swing.*; import java.awt.*; @@ -44,7 +44,7 @@ import java.util.List; /** * @author egor */ -public class JavaBreakpointPropertiesPanel extends XBreakpointCustomPropertiesPanel<XLineBreakpoint<XBreakpointProperties>> { +public class JavaBreakpointFiltersPanel<T extends JavaBreakpointProperties, B extends XBreakpoint<T>> extends XBreakpointCustomPropertiesPanel<B> { private JPanel myConditionsPanel; private JPanel myInstanceFiltersPanel; private JCheckBox myInstanceFiltersCheckBox; @@ -66,7 +66,7 @@ public class JavaBreakpointPropertiesPanel extends XBreakpointCustomPropertiesPa private PsiClass myBreakpointPsiClass; - public JavaBreakpointPropertiesPanel(Project project) { + public JavaBreakpointFiltersPanel(Project project) { myProject = project; myInstanceFiltersField = new FieldPanel(new MyTextField(), "", null, new ActionListener() { @@ -135,8 +135,8 @@ public class JavaBreakpointPropertiesPanel extends XBreakpointCustomPropertiesPa } @Override - public boolean isVisibleOnPopup(@NotNull XLineBreakpoint<XBreakpointProperties> breakpoint) { - JavaBreakpointProperties properties = (JavaBreakpointProperties)breakpoint.getProperties(); + public boolean isVisibleOnPopup(@NotNull B breakpoint) { + JavaBreakpointProperties properties = breakpoint.getProperties(); if (properties != null) { return properties.COUNT_FILTER_ENABLED || properties.CLASS_FILTERS_ENABLED || properties.INSTANCE_FILTERS_ENABLED; } @@ -144,8 +144,8 @@ public class JavaBreakpointPropertiesPanel extends XBreakpointCustomPropertiesPa } @Override - public void saveTo(@NotNull XLineBreakpoint<XBreakpointProperties> breakpoint) { - JavaBreakpointProperties properties = (JavaBreakpointProperties)breakpoint.getProperties(); + public void saveTo(@NotNull B breakpoint) { + JavaBreakpointProperties properties = breakpoint.getProperties(); if (properties == null) { return; } @@ -179,8 +179,8 @@ public class JavaBreakpointPropertiesPanel extends XBreakpointCustomPropertiesPa } @Override - public void loadFrom(@NotNull XLineBreakpoint<XBreakpointProperties> breakpoint) { - JavaBreakpointProperties properties = (JavaBreakpointProperties)breakpoint.getProperties(); + public void loadFrom(@NotNull B breakpoint) { + JavaBreakpointProperties properties = breakpoint.getProperties(); if (properties != null) { if (properties.COUNT_FILTER > 0) { myPassCountField.setText(Integer.toString(properties.COUNT_FILTER)); 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 deleted file mode 100644 index 5e55a49658f8..000000000000 --- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointType.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.jetbrains.java.debugger.breakpoints; - -import com.intellij.debugger.DebuggerBundle; -import com.intellij.debugger.engine.DebuggerUtils; -import com.intellij.openapi.fileTypes.FileType; -import com.intellij.openapi.fileTypes.StdFileTypes; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiManager; -import com.intellij.util.SystemProperties; -import com.intellij.xdebugger.XDebuggerUtil; -import com.intellij.xdebugger.breakpoints.XBreakpointProperties; -import com.intellij.xdebugger.breakpoints.XLineBreakpoint; -import com.intellij.xdebugger.breakpoints.XLineBreakpointTypeBase; -import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; -import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.java.debugger.JavaDebuggerEditorsProvider; - -import java.util.List; - -public class JavaBreakpointType extends XLineBreakpointTypeBase { - public JavaBreakpointType() { - super("java", DebuggerBundle.message("java.breakpoint.title"), new JavaDebuggerEditorsProvider()); - } - - @Override - public boolean canPutAt(@NotNull final VirtualFile file, final int line, @NotNull Project project) { - return SystemProperties.getBooleanProperty("java.debugger.xBreakpoint", false) && - doCanPutAt(PsiManager.getInstance(project).findFile(file)); - } - - @Override - public boolean isSuspendThreadSupported() { - return true; - } - - @Override - public List<XBreakpointGroupingRule<XLineBreakpoint<XBreakpointProperties>, ?>> getGroupingRules() { - return XDebuggerUtil.getInstance().getGroupingByFileRuleAsList(); - } - - @Contract("null -> false") - public static boolean doCanPutAt(@Nullable PsiFile psiFile) { - // JSPX supports jvm debugging, but not in XHTML files - if (psiFile == null || psiFile.getVirtualFile().getFileType() == StdFileTypes.XHTML) { - return false; - } - - FileType fileType = psiFile.getFileType(); - return StdFileTypes.CLASS.equals(fileType) || DebuggerUtils.supportsJVMDebugging(fileType) || DebuggerUtils.supportsJVMDebugging(psiFile); - } - - @Nullable - @Override - public XBreakpointProperties createProperties() { - return new JavaBreakpointProperties(); - } - - @Nullable - @Override - public XBreakpointProperties createBreakpointProperties(@NotNull VirtualFile file, int line) { - return new JavaBreakpointProperties(); - } - - @Nullable - @Override - public XBreakpointCustomPropertiesPanel<XLineBreakpoint<XBreakpointProperties>> createCustomRightPropertiesPanel(@NotNull Project project) { - return new JavaBreakpointPropertiesPanel(project); - } - - -}
\ No newline at end of file diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointProperties.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaBreakpointProperties.java index e2f3202a0d46..daab63a93265 100644 --- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointProperties.java +++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaBreakpointProperties.java @@ -13,27 +13,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.java.debugger.breakpoints; +package org.jetbrains.java.debugger.breakpoints.properties; import com.intellij.debugger.InstanceFilter; import com.intellij.ui.classFilter.ClassFilter; +import com.intellij.util.xmlb.annotations.AbstractCollection; +import com.intellij.util.xmlb.annotations.OptionTag; +import com.intellij.util.xmlb.annotations.Tag; import com.intellij.xdebugger.breakpoints.XBreakpointProperties; import org.jetbrains.annotations.Nullable; /** * @author egor */ -public class JavaBreakpointProperties extends XBreakpointProperties<JavaBreakpointProperties> { +public class JavaBreakpointProperties<T extends JavaBreakpointProperties> extends XBreakpointProperties<T> { + @OptionTag("count-filter-enabled") public boolean COUNT_FILTER_ENABLED = false; + @OptionTag("count-filter") public int COUNT_FILTER = 0; + @OptionTag("class-filters-enabled") public boolean CLASS_FILTERS_ENABLED = false; private ClassFilter[] myClassFilters; private ClassFilter[] myClassExclusionFilters; + @OptionTag("instance-filters-enabled") public boolean INSTANCE_FILTERS_ENABLED = false; private InstanceFilter[] myInstanceFilters; + @Tag("instance-filters") + @AbstractCollection(surroundWithTag = false) public InstanceFilter[] getInstanceFilters() { return myInstanceFilters != null ? myInstanceFilters : InstanceFilter.EMPTY_ARRAY; } @@ -42,13 +51,15 @@ public class JavaBreakpointProperties extends XBreakpointProperties<JavaBreakpoi myInstanceFilters = instanceFilters; } - protected void addInstanceFilter(long l) { + public void addInstanceFilter(long l) { final InstanceFilter[] filters = new InstanceFilter[myInstanceFilters.length + 1]; System.arraycopy(myInstanceFilters, 0, filters, 0, myInstanceFilters.length); filters[myInstanceFilters.length] = InstanceFilter.create(String.valueOf(l)); myInstanceFilters = filters; } + @Tag("class-filters") + @AbstractCollection(surroundWithTag = false) public final ClassFilter[] getClassFilters() { return myClassFilters != null ? myClassFilters : ClassFilter.EMPTY_ARRAY; } @@ -57,6 +68,8 @@ public class JavaBreakpointProperties extends XBreakpointProperties<JavaBreakpoi myClassFilters = classFilters; } + @Tag("class-exclusion-filters") + @AbstractCollection(surroundWithTag = false) public ClassFilter[] getClassExclusionFilters() { return myClassExclusionFilters != null ? myClassExclusionFilters : ClassFilter.EMPTY_ARRAY; } @@ -67,20 +80,20 @@ public class JavaBreakpointProperties extends XBreakpointProperties<JavaBreakpoi @Nullable @Override - public JavaBreakpointProperties getState() { - return this; + public T getState() { + return (T)this; } @Override - public void loadState(JavaBreakpointProperties state) { + public void loadState(T state) { COUNT_FILTER_ENABLED = state.COUNT_FILTER_ENABLED; COUNT_FILTER = state.COUNT_FILTER; CLASS_FILTERS_ENABLED = state.CLASS_FILTERS_ENABLED; - myClassFilters = state.myClassFilters; - myClassExclusionFilters = state.myClassExclusionFilters; + myClassFilters = state.getClassFilters(); + myClassExclusionFilters = state.getClassExclusionFilters(); INSTANCE_FILTERS_ENABLED = state.INSTANCE_FILTERS_ENABLED; - myInstanceFilters = state.myInstanceFilters; + myInstanceFilters = state.getInstanceFilters(); } } diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaExceptionBreakpointProperties.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaExceptionBreakpointProperties.java new file mode 100644 index 000000000000..e3b893e926ee --- /dev/null +++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaExceptionBreakpointProperties.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.java.debugger.breakpoints.properties; + +import com.intellij.util.xmlb.annotations.Attribute; +import org.jetbrains.annotations.Nullable; + +/** + * @author egor + */ +public class JavaExceptionBreakpointProperties extends JavaBreakpointProperties<JavaExceptionBreakpointProperties> { + public boolean NOTIFY_CAUGHT = true; + public boolean NOTIFY_UNCAUGHT = true; + + @Attribute("class") + public String myQualifiedName; + + @Attribute("package") + public String myPackageName; + + public JavaExceptionBreakpointProperties(String qualifiedName, String packageName) { + myQualifiedName = qualifiedName; + myPackageName = packageName; + } + + public JavaExceptionBreakpointProperties() { + } + + @Nullable + @Override + public JavaExceptionBreakpointProperties getState() { + return this; + } + + @Override + public void loadState(JavaExceptionBreakpointProperties state) { + super.loadState(state); + + NOTIFY_CAUGHT = state.NOTIFY_CAUGHT; + NOTIFY_UNCAUGHT = state.NOTIFY_UNCAUGHT; + myQualifiedName = state.myQualifiedName; + myPackageName = state.myPackageName; + } +} diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaFieldBreakpointProperties.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaFieldBreakpointProperties.java new file mode 100644 index 000000000000..13b760e81428 --- /dev/null +++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaFieldBreakpointProperties.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.java.debugger.breakpoints.properties; + +import com.intellij.util.xmlb.annotations.Attribute; +import org.jetbrains.annotations.Nullable; + +/** + * @author egor + */ +public class JavaFieldBreakpointProperties extends JavaBreakpointProperties<JavaFieldBreakpointProperties> { + public boolean WATCH_MODIFICATION = true; + public boolean WATCH_ACCESS = false; + + @Attribute("field") + public String myFieldName; + + @Attribute("class") + public String myClassName; + + public JavaFieldBreakpointProperties(String fieldName, String className) { + myFieldName = fieldName; + myClassName = className; + } + + public JavaFieldBreakpointProperties() { + } + + @Nullable + @Override + public JavaFieldBreakpointProperties getState() { + return this; + } + + @Override + public void loadState(JavaFieldBreakpointProperties state) { + super.loadState(state); + + WATCH_MODIFICATION = state.WATCH_MODIFICATION; + WATCH_ACCESS = state.WATCH_ACCESS; + myFieldName = state.myFieldName; + myClassName = state.myClassName; + } +} diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaLineBreakpointProperties.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaLineBreakpointProperties.java new file mode 100644 index 000000000000..9a892346ac04 --- /dev/null +++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaLineBreakpointProperties.java @@ -0,0 +1,22 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.java.debugger.breakpoints.properties; + +/** + * @author egor + */ +public class JavaLineBreakpointProperties extends JavaBreakpointProperties<JavaLineBreakpointProperties> { +} diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaMethodBreakpointProperties.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaMethodBreakpointProperties.java new file mode 100644 index 000000000000..9392b565645b --- /dev/null +++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaMethodBreakpointProperties.java @@ -0,0 +1,58 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.java.debugger.breakpoints.properties; + +import com.intellij.util.xmlb.annotations.Attribute; +import org.jetbrains.annotations.Nullable; + +/** + * @author egor + */ +public class JavaMethodBreakpointProperties extends JavaBreakpointProperties<JavaMethodBreakpointProperties> { + @Attribute("class") + public String myClassPattern; + + @Attribute("method") + public String myMethodName; + + public boolean WATCH_ENTRY = true; + public boolean WATCH_EXIT = true; + + public JavaMethodBreakpointProperties(String classPattern, String methodName) { + myClassPattern = classPattern; + myMethodName = methodName; + } + + public JavaMethodBreakpointProperties() { + } + + @Nullable + @Override + public JavaMethodBreakpointProperties getState() { + return this; + } + + @Override + public void loadState(JavaMethodBreakpointProperties state) { + super.loadState(state); + + myClassPattern = state.myClassPattern; + myMethodName = state.myMethodName; + + WATCH_ENTRY = state.WATCH_ENTRY; + WATCH_EXIT = state.WATCH_EXIT; + } +} diff --git a/java/debugger/openapi/src/com/intellij/debugger/PositionManagerEx.java b/java/debugger/openapi/src/com/intellij/debugger/PositionManagerEx.java new file mode 100644 index 000000000000..c1faee1f763f --- /dev/null +++ b/java/debugger/openapi/src/com/intellij/debugger/PositionManagerEx.java @@ -0,0 +1,26 @@ +/* + * 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.debugger; + +import com.intellij.xdebugger.frame.XStackFrame; +import com.sun.jdi.Location; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public abstract class PositionManagerEx implements PositionManager { + @Nullable + public abstract XStackFrame createStackFrame(@NotNull Location location); +} diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcess.java b/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcess.java index 66fea2d7f38c..43c7fd47f02f 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcess.java +++ b/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcess.java @@ -16,6 +16,7 @@ package com.intellij.debugger.engine; import com.intellij.debugger.PositionManager; +import com.intellij.debugger.PositionManagerEx; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluationContext; import com.intellij.debugger.engine.jdi.VirtualMachineProxy; @@ -44,7 +45,7 @@ public interface DebugProcess { RequestManager getRequestsManager(); - PositionManager getPositionManager(); + PositionManagerEx getPositionManager(); VirtualMachineProxy getVirtualMachineProxy(); diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java b/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java index 1697684b9d21..b200e0ef1829 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java +++ b/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java @@ -80,6 +80,7 @@ public abstract class JSR45PositionManager<Scope> implements PositionManager { return myStratumId; } + @Override public SourcePosition getSourcePosition(final Location location) throws NoDataException { SourcePosition sourcePosition = null; @@ -110,6 +111,7 @@ public abstract class JSR45PositionManager<Scope> implements PositionManager { return location.lineNumber(myStratumId); } + @Override @NotNull public List<ReferenceType> getAllClasses(SourcePosition classPosition) throws NoDataException { checkSourcePositionFileType(classPosition); @@ -138,6 +140,7 @@ public abstract class JSR45PositionManager<Scope> implements PositionManager { } } + @Override @NotNull public List<Location> locationsOfLine(final ReferenceType type, final SourcePosition position) throws NoDataException { List<Location> locations = locationsOfClassAt(type, position); @@ -149,6 +152,7 @@ public abstract class JSR45PositionManager<Scope> implements PositionManager { checkSourcePositionFileType(position); return ApplicationManager.getApplication().runReadAction(new Computable<List<Location>>() { + @Override public List<Location> compute() { try { final List<String> relativePaths = getRelativeSourePathsByType(type); @@ -165,7 +169,7 @@ public abstract class JSR45PositionManager<Scope> implements PositionManager { } catch(ClassNotPreparedException ignored) { } - catch (InternalError e) { + catch (InternalError ignored) { myDebugProcess.getExecutionResult().getProcessHandler().notifyTextAvailable( DebuggerBundle.message("internal.error.locations.of.line", type.name()), ProcessOutputTypes.SYSTEM); } @@ -176,7 +180,7 @@ public abstract class JSR45PositionManager<Scope> implements PositionManager { // This is needed because some servers (e.g. WebSphere) put not exact file name such as 'A.jsp ' private String getSourceName(final String name, final ReferenceType type) throws AbsentInformationException { for(String sourceNameFromType: type.sourceNames(myStratumId)) { - if (sourceNameFromType.indexOf(name) >= 0) { + if (sourceNameFromType.contains(name)) { return sourceNameFromType; } } @@ -199,11 +203,13 @@ public abstract class JSR45PositionManager<Scope> implements PositionManager { return type.locationsOfLine(myStratumId, fileName, lineNumber); } + @Override public ClassPrepareRequest createPrepareRequest(final ClassPrepareRequestor requestor, final SourcePosition position) throws NoDataException { checkSourcePositionFileType(position); return myDebugProcess.getRequestsManager().createClassPrepareRequest(new ClassPrepareRequestor() { + @Override public void processClassPrepare(DebugProcess debuggerProcess, ReferenceType referenceType) { onClassPrepare(debuggerProcess, referenceType, position, requestor); } @@ -217,7 +223,7 @@ public abstract class JSR45PositionManager<Scope> implements PositionManager { requestor.processClassPrepare(debuggerProcess, referenceType); } } - catch (NoDataException e) { + catch (NoDataException ignored) { } } diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/StackFrameProxy.java b/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/StackFrameProxy.java index 7e0b6ee007f1..511b1af39daf 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/StackFrameProxy.java +++ b/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/StackFrameProxy.java @@ -19,6 +19,7 @@ import com.intellij.debugger.engine.evaluation.EvaluateException; import com.sun.jdi.ClassLoaderReference; import com.sun.jdi.Location; import com.sun.jdi.StackFrame; +import org.jetbrains.annotations.Nullable; public interface StackFrameProxy extends ObjectReferenceProxy{ StackFrame getStackFrame() throws EvaluateException; @@ -27,6 +28,7 @@ public interface StackFrameProxy extends ObjectReferenceProxy{ VirtualMachineProxy getVirtualMachine(); + @Nullable Location location() throws EvaluateException; ClassLoaderReference getClassLoader() throws EvaluateException; diff --git a/java/idea-ui/src/com/intellij/ide/impl/ProjectStructureSelectInTarget.java b/java/idea-ui/src/com/intellij/ide/impl/ProjectStructureSelectInTarget.java index d282c684e3db..70457eb6bdf3 100644 --- a/java/idea-ui/src/com/intellij/ide/impl/ProjectStructureSelectInTarget.java +++ b/java/idea-ui/src/com/intellij/ide/impl/ProjectStructureSelectInTarget.java @@ -18,6 +18,7 @@ package com.intellij.ide.impl; import com.intellij.facet.*; import com.intellij.ide.*; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.DumbAware; @@ -48,7 +49,8 @@ public class ProjectStructureSelectInTarget extends SelectInTargetBase implement final Object o = ((WrappingVirtualFile)file).getWrappedObject(context.getProject()); return o instanceof Facet; } - return fileIndex.isInContent(file) || fileIndex.isInLibraryClasses(file) || fileIndex.isInLibrarySource(file); + return fileIndex.isInContent(file) || fileIndex.isInLibraryClasses(file) || fileIndex.isInLibrarySource(file) + || StdFileTypes.IDEA_MODULE.equals(file.getFileType()) && findModuleByModuleFile(context.getProject(), file) != null; } @Override @@ -64,8 +66,9 @@ public class ProjectStructureSelectInTarget extends SelectInTargetBase implement module = facet == null? null : facet.getModule(); } else { + Module moduleByIml = file.getFileType().equals(StdFileTypes.IDEA_MODULE) ? findModuleByModuleFile(project, file) : null; final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); - module = fileIndex.getModuleForFile(file); + module = moduleByIml != null ? moduleByIml : fileIndex.getModuleForFile(file); facet = fileIndex.isInSourceContent(file) ? null : findFacet(project, file); } if (module != null || facet != null) { @@ -95,6 +98,16 @@ public class ProjectStructureSelectInTarget extends SelectInTargetBase implement } @Nullable + private static Module findModuleByModuleFile(@NotNull Project project, @NotNull VirtualFile file) { + for (Module module : ModuleManager.getInstance(project).getModules()) { + if (file.equals(module.getModuleFile())) { + return module; + } + } + return null; + } + + @Nullable private static Facet findFacet(final @NotNull Project project, final @NotNull VirtualFile file) { for (FacetTypeId id : FacetTypeRegistry.getInstance().getFacetTypeIds()) { if (hasFacetWithRoots(project, id)) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java index 324a222a018d..72ad0f26efa1 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java @@ -406,8 +406,9 @@ public class GenericsHighlightUtil { if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && aClass.isInterface() && method.hasModifierProperty(PsiModifier.DEFAULT)) { HierarchicalMethodSignature sig = method.getHierarchicalMethodSignature(); for (HierarchicalMethodSignature methodSignature : sig.getSuperSignatures()) { - final PsiClass containingClass = methodSignature.getMethod().getContainingClass(); - if (containingClass != null && CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName())) { + final PsiMethod objectMethod = methodSignature.getMethod(); + final PsiClass containingClass = objectMethod.getContainingClass(); + if (containingClass != null && CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName()) && objectMethod.hasModifierProperty(PsiModifier.PUBLIC)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .descriptionAndTooltip("Default method '" + sig.getName() + "' overrides a member of 'java.lang.Object'") .range(methodIdentifier) 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 4e9d79fecf57..352e74557eed 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 @@ -1324,8 +1324,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh myHolder.add(GenericsHighlightUtil.checkParametersAllowed(list, myLanguageLevel,myFile)); if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkParametersOnRaw(list)); if (!myHolder.hasErrorResults()) { - for (PsiType type : list.getTypeArguments()) { - myHolder.add(HighlightUtil.checkDiamondFeature(type, list, myLanguageLevel,myFile)); + for (PsiTypeElement typeElement : list.getTypeParameterElements()) { + myHolder.add(HighlightUtil.checkDiamondFeature(typeElement.getType(), list, myLanguageLevel,myFile)); } } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java index b9c5d21bcd5e..a5104f1deb51 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,10 +33,11 @@ import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; -import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static com.intellij.util.ObjectUtils.assertNotNull; + public class AddTypeCastFix extends LocalQuickFixAndIntentionActionOnPsiElement { private final PsiType myType; @@ -75,28 +76,26 @@ public class AddTypeCastFix extends LocalQuickFixAndIntentionActionOnPsiElement addTypeCast(project, (PsiExpression)startElement, myType); } - private static void addTypeCast(Project project, PsiExpression originalExpression, PsiType type) throws IncorrectOperationException { + private static void addTypeCast(Project project, PsiExpression originalExpression, PsiType type) { PsiExpression typeCast = createCastExpression(originalExpression, project, type); originalExpression.replace(typeCast); } - static PsiExpression createCastExpression(PsiExpression originalExpression, Project project, PsiType type) throws IncorrectOperationException { + static PsiExpression createCastExpression(PsiExpression originalExpression, Project project, PsiType type) { // remove nested casts - PsiElement element = PsiUtil.deparenthesizeExpression(originalExpression); - if (element == null){ - return null; - } - PsiElementFactory factory = JavaPsiFacade.getInstance(originalExpression.getProject()).getElementFactory(); + PsiElement expression = PsiUtil.deparenthesizeExpression(originalExpression); + if (expression == null) return null; + PsiElementFactory factory = JavaPsiFacade.getInstance(originalExpression.getProject()).getElementFactory(); PsiTypeCastExpression typeCast = (PsiTypeCastExpression)factory.createExpressionFromText("(Type)value", null); + assertNotNull(typeCast.getCastType()).replace(factory.createTypeElement(type)); typeCast = (PsiTypeCastExpression)CodeStyleManager.getInstance(project).reformat(typeCast); - typeCast.getCastType().replace(factory.createTypeElement(type)); - if (element instanceof PsiConditionalExpression) { - // we'd better cast one branch of ternary expression if we could - PsiConditionalExpression expression = (PsiConditionalExpression)element.copy(); - PsiExpression thenE = expression.getThenExpression(); - PsiExpression elseE = expression.getElseExpression(); + if (expression instanceof PsiConditionalExpression) { + // we'd better cast one branch of ternary expression if we can + PsiConditionalExpression conditional = (PsiConditionalExpression)expression.copy(); + PsiExpression thenE = conditional.getThenExpression(); + PsiExpression elseE = conditional.getElseExpression(); PsiType thenType = thenE == null ? null : thenE.getType(); PsiType elseType = elseE == null ? null : elseE.getType(); if (elseType != null && thenType != null) { @@ -104,18 +103,20 @@ public class AddTypeCastFix extends LocalQuickFixAndIntentionActionOnPsiElement boolean replaceElse = !TypeConversionUtil.isAssignable(type, elseType); if (replaceThen != replaceElse) { if (replaceThen) { - typeCast.getOperand().replace(thenE); + assertNotNull(typeCast.getOperand()).replace(thenE); thenE.replace(typeCast); } else { - typeCast.getOperand().replace(elseE); + assertNotNull(typeCast.getOperand()).replace(elseE); elseE.replace(typeCast); } - return expression; + return conditional; } } } - typeCast.getOperand().replace(element); + + assertNotNull(typeCast.getOperand()).replace(expression); + return typeCast; } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java index 76580adaa5f4..b4a8d5b99d17 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,14 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/** - * Created by IntelliJ IDEA. - * User: cdr - * Date: Nov 13, 2002 - * Time: 3:26:50 PM - * To change this template use Options | File Templates. - */ package com.intellij.codeInsight.daemon.impl.quickfix; import com.intellij.codeInsight.FileModificationService; @@ -32,6 +24,7 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.TypeConversionUtil; @@ -39,11 +32,18 @@ import com.intellij.util.Function; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static com.intellij.util.ObjectUtils.assertNotNull; + +/** + * @author cdr + * @since Nov 13, 2002 + */ public class ChangeTypeArgumentsFix implements IntentionAction, HighPriorityAction { + private static final Logger LOG = Logger.getInstance("#" + ChangeTypeArgumentsFix.class.getName()); + private final PsiMethod myTargetMethod; private final PsiClass myPsiClass; private final PsiExpression[] myExpressions; - private static final Logger LOG = Logger.getInstance("#" + ChangeTypeArgumentsFix.class.getName()); private final PsiNewExpression myNewExpression; ChangeTypeArgumentsFix(@NotNull PsiMethod targetMethod, @@ -116,11 +116,12 @@ public class ChangeTypeArgumentsFix implements IntentionAction, HighPriorityActi LOG.assertTrue(reference != null, myNewExpression); final PsiReferenceParameterList parameterList = reference.getParameterList(); LOG.assertTrue(parameterList != null, myNewExpression); + PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); PsiTypeElement[] elements = parameterList.getTypeParameterElements(); for (int i = elements.length - 1; i >= 0; i--) { - PsiTypeElement typeElement = elements[i]; - final PsiType typeArg = psiSubstitutor.substitute(typeParameters[i]); - typeElement.replace(JavaPsiFacade.getElementFactory(project).createTypeElement(typeArg)); + PsiType typeArg = assertNotNull(psiSubstitutor.substitute(typeParameters[i])); + PsiElement replaced = elements[i].replace(factory.createTypeElement(typeArg)); + JavaCodeStyleManager.getInstance(file.getProject()).shortenClassReferences(replaced); } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java index 987f02dc9c39..84f704f64dcd 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java @@ -64,15 +64,25 @@ public class AddAnnotationPsiFix extends LocalQuickFixOnPsiElement { } @Nullable - public static PsiModifierListOwner getContainer(final PsiElement element) { - PsiModifierListOwner listOwner = PsiTreeUtil.getParentOfType(element, PsiParameter.class, false); - if (listOwner == null) { - final PsiIdentifier psiIdentifier = PsiTreeUtil.getParentOfType(element, PsiIdentifier.class, false); - if (psiIdentifier != null && psiIdentifier.getParent() instanceof PsiModifierListOwner) { - listOwner = (PsiModifierListOwner)psiIdentifier.getParent(); + public static PsiModifierListOwner getContainer(final PsiFile file, int offset) { + PsiReference reference = file.findReferenceAt(offset); + if (reference != null) { + PsiElement target = reference.resolve(); + if (target instanceof PsiMember) { + return (PsiMember)target; } } - return listOwner; + + PsiElement element = file.findElementAt(offset); + + PsiModifierListOwner listOwner = PsiTreeUtil.getParentOfType(element, PsiParameter.class, false); + if (listOwner != null) return listOwner; + + final PsiIdentifier psiIdentifier = PsiTreeUtil.getParentOfType(element, PsiIdentifier.class, false); + if (psiIdentifier != null && psiIdentifier.getParent() instanceof PsiModifierListOwner) { + return (PsiModifierListOwner)psiIdentifier.getParent(); + } + return null; } @Override diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java index 6684613f0ab0..272ce37708ad 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java @@ -41,7 +41,7 @@ public class AddNullableNotNullAnnotationFix extends AddAnnotationPsiFix { if (!super.isAvailable(project, file, startElement, endElement)) { return false; } - PsiModifierListOwner owner = getContainer(startElement); + PsiModifierListOwner owner = getContainer(file, startElement.getTextRange().getStartOffset()); if (owner == null || AnnotationUtil.isAnnotated(owner, getAnnotationsToRemove()[0], false, false)) { return false; } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java index ed3494096265..b89473e29b83 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java @@ -22,6 +22,7 @@ import com.intellij.codeInsight.intention.HighPriorityAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; @@ -97,8 +98,11 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection final String localName = local.getName(); if (localName != null && helper.resolveReferencedVariable(localName, aClass) != null) return; } - holder.registerProblem(aClass.getBaseClassReference(), "Anonymous #ref #loc can be replaced with lambda", - ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new ReplaceWithLambdaFix()); + final PsiElement lBrace = aClass.getLBrace(); + LOG.assertTrue(lBrace != null); + final TextRange rangeInElement = new TextRange(0, aClass.getStartOffsetInParent() + lBrace.getStartOffsetInParent()); + holder.registerProblem(aClass.getParent(), "Anonymous #ref #loc can be replaced with lambda", + ProblemHighlightType.LIKE_UNUSED_SYMBOL, rangeInElement, new ReplaceWithLambdaFix()); } } } @@ -125,8 +129,8 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { final PsiElement element = descriptor.getPsiElement(); - if (element != null) { - final PsiAnonymousClass anonymousClass = PsiTreeUtil.getParentOfType(element, PsiAnonymousClass.class); + if (element instanceof PsiNewExpression) { + final PsiAnonymousClass anonymousClass = ((PsiNewExpression)element).getAnonymousClass(); LOG.assertTrue(anonymousClass != null); ChangeContextUtil.encodeContextInfo(anonymousClass, true); final PsiElement lambdaContext = anonymousClass.getParent().getParent(); 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 6ad6d223b5a0..6eec61428cda 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java @@ -18,10 +18,10 @@ package com.intellij.codeInspection; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; import com.intellij.pom.java.LanguageLevel; 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.RedundantCastUtil; import org.jetbrains.annotations.Nls; @@ -79,8 +79,11 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI if (parent instanceof PsiNewExpression) { final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)parent).getClassOrAnonymousClassReference(); if (classReference != null) { - holder.registerProblem(classReference, - "Anonymous #ref #loc can be replaced with method reference", new ReplaceWithMethodRefFix()); + final PsiElement lBrace = aClass.getLBrace(); + LOG.assertTrue(lBrace != null); + final TextRange rangeInElement = new TextRange(0, aClass.getStartOffsetInParent() + lBrace.getStartOffsetInParent()); + holder.registerProblem(parent, + "Anonymous #ref #loc can be replaced with method reference", ProblemHighlightType.LIKE_UNUSED_SYMBOL, rangeInElement, new ReplaceWithMethodRefFix()); } } } @@ -107,29 +110,31 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { final PsiElement element = descriptor.getPsiElement(); - final PsiAnonymousClass anonymousClass = PsiTreeUtil.getParentOfType(element, PsiAnonymousClass.class); - if (anonymousClass == null) return; - final PsiMethod[] methods = anonymousClass.getMethods(); - if (methods.length != 1) return; + if (element instanceof PsiNewExpression) { + final PsiAnonymousClass anonymousClass = ((PsiNewExpression)element).getAnonymousClass(); + if (anonymousClass == null) return; + final PsiMethod[] methods = anonymousClass.getMethods(); + if (methods.length != 1) return; - final PsiParameter[] parameters = methods[0].getParameterList().getParameters(); - final PsiCallExpression callExpression = LambdaCanBeMethodReferenceInspection - .canBeMethodReferenceProblem(methods[0].getBody(), parameters, anonymousClass.getBaseClassType()); - if (callExpression == null) return; - final String methodRefText = - LambdaCanBeMethodReferenceInspection.createMethodReferenceText(callExpression, anonymousClass.getBaseClassType(), parameters); + final PsiParameter[] parameters = methods[0].getParameterList().getParameters(); + final PsiCallExpression callExpression = LambdaCanBeMethodReferenceInspection + .canBeMethodReferenceProblem(methods[0].getBody(), parameters, anonymousClass.getBaseClassType()); + if (callExpression == null) return; + final String methodRefText = + LambdaCanBeMethodReferenceInspection.createMethodReferenceText(callExpression, anonymousClass.getBaseClassType(), parameters); - if (methodRefText != null) { - final String canonicalText = anonymousClass.getBaseClassType().getCanonicalText(); - final PsiExpression psiExpression = JavaPsiFacade.getElementFactory(project).createExpressionFromText("(" + canonicalText + ")" + methodRefText, anonymousClass); - - PsiElement castExpr = anonymousClass.getParent().replace(psiExpression); - if (RedundantCastUtil.isCastRedundant((PsiTypeCastExpression)castExpr)) { - final PsiExpression operand = ((PsiTypeCastExpression)castExpr).getOperand(); - LOG.assertTrue(operand != null); - castExpr = castExpr.replace(operand); + if (methodRefText != null) { + final String canonicalText = anonymousClass.getBaseClassType().getCanonicalText(); + final PsiExpression psiExpression = JavaPsiFacade.getElementFactory(project).createExpressionFromText("(" + canonicalText + ")" + methodRefText, anonymousClass); + + PsiElement castExpr = anonymousClass.getParent().replace(psiExpression); + if (RedundantCastUtil.isCastRedundant((PsiTypeCastExpression)castExpr)) { + final PsiExpression operand = ((PsiTypeCastExpression)castExpr).getOperand(); + LOG.assertTrue(operand != null); + castExpr = castExpr.replace(operand); + } + JavaCodeStyleManager.getInstance(project).shortenClassReferences(castExpr); } - JavaCodeStyleManager.getInstance(project).shortenClassReferences(castExpr); } } } 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 8a8a6db0752e..9bc2a6ecacc2 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java @@ -88,27 +88,7 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp protected static PsiCallExpression canBeMethodReferenceProblem(@Nullable final PsiElement body, final PsiParameter[] parameters, PsiType functionalInterfaceType) { - PsiCallExpression methodCall = null; - if (body instanceof PsiCallExpression) { - methodCall = (PsiCallExpression)body; - } - else if (body instanceof PsiCodeBlock) { - final PsiStatement[] statements = ((PsiCodeBlock)body).getStatements(); - if (statements.length == 1) { - if (statements[0] instanceof PsiReturnStatement) { - final PsiExpression returnValue = ((PsiReturnStatement)statements[0]).getReturnValue(); - if (returnValue instanceof PsiCallExpression) { - methodCall = (PsiCallExpression)returnValue; - } - } - else if (statements[0] instanceof PsiExpressionStatement) { - final PsiExpression expr = ((PsiExpressionStatement)statements[0]).getExpression(); - if (expr instanceof PsiCallExpression) { - methodCall = (PsiCallExpression)expr; - } - } - } - } + PsiCallExpression methodCall = extractMethodCallFromBlock(body); if (methodCall != null) { final PsiExpressionList argumentList = methodCall.getArgumentList(); @@ -218,6 +198,40 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp return null; } + public static PsiCallExpression extractMethodCallFromBlock(PsiElement body) { + PsiCallExpression methodCall = null; + if (body instanceof PsiCallExpression) { + methodCall = (PsiCallExpression)body; + } + else if (body instanceof PsiCodeBlock) { + final PsiStatement[] statements = ((PsiCodeBlock)body).getStatements(); + if (statements.length == 1) { + if (statements[0] instanceof PsiReturnStatement) { + final PsiExpression returnValue = ((PsiReturnStatement)statements[0]).getReturnValue(); + if (returnValue instanceof PsiCallExpression) { + methodCall = (PsiCallExpression)returnValue; + } + } + else if (statements[0] instanceof PsiExpressionStatement) { + final PsiExpression expr = ((PsiExpressionStatement)statements[0]).getExpression(); + if (expr instanceof PsiCallExpression) { + methodCall = (PsiCallExpression)expr; + } + } + } + } + else if (body instanceof PsiBlockStatement) { + return extractMethodCallFromBlock(((PsiBlockStatement)body).getCodeBlock()); + } + else if (body instanceof PsiExpressionStatement) { + final PsiExpression expression = ((PsiExpressionStatement)body).getExpression(); + if (expression instanceof PsiCallExpression) { + methodCall = (PsiCallExpression)expression; + } + } + return methodCall; + } + @Nullable private static PsiMethod ensureNonAmbiguousMethod(PsiParameter[] parameters, @NotNull PsiMethod psiMethod) { String methodName = psiMethod.getName(); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java index 8101d16f5a1e..919fb4ea28db 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java @@ -21,7 +21,9 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.controlFlow.*; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; @@ -106,9 +108,14 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo } }); - if (effectivelyFinal[0] && !isTrivial(body, statement.getIterationParameter(), iteratedValueType)) { - holder.registerProblem(iteratedValue, "Can be replaced with foreach call", - ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new ReplaceWithForeachCallFix()); + if (effectivelyFinal[0]) { + if (isCollectCall(body)) { + holder.registerProblem(iteratedValue, "Can be replaced with collect call", + ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new ReplaceWithCollectCallFix()); + } else if (!isTrivial(body, statement.getIterationParameter(), iteratedValueType)) { + holder.registerProblem(iteratedValue, "Can be replaced with foreach call", + ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new ReplaceWithForeachCallFix()); + } } } } @@ -121,10 +128,46 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo }; } + private static boolean isCollectCall(PsiStatement body) { + final PsiMethodCallExpression methodCallExpression = extractAddCall(body); + if (methodCallExpression != null) { + final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); + final PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); + PsiClass qualifierClass = null; + if (qualifierExpression instanceof PsiReferenceExpression) { + qualifierClass = PsiUtil.resolveClassInType(qualifierExpression.getType()); + } else if (qualifierExpression == null) { + final PsiClass enclosingClass = PsiTreeUtil.getParentOfType(body, PsiClass.class); + if (PsiUtil.getEnclosingStaticElement(body, enclosingClass) == null) { + qualifierClass = enclosingClass; + } + } + + if (qualifierClass != null && + InheritanceUtil.isInheritor(qualifierClass, false, CommonClassNames.JAVA_UTIL_COLLECTION)) { + + final PsiElement resolve = methodExpression.resolve(); + if (resolve instanceof PsiMethod && + "add".equals(((PsiMethod)resolve).getName()) && + ((PsiMethod)resolve).getParameterList().getParametersCount() == 1) { + final PsiExpression[] args = methodCallExpression.getArgumentList().getExpressions(); + if (args.length == 1) { + if (args[0] instanceof PsiCallExpression) { + final PsiMethod method = ((PsiCallExpression)args[0]).resolveMethod(); + return method != null && !method.hasTypeParameters(); + } + return true; + } + } + } + } + return false; + } + private static boolean isTrivial(PsiStatement body, PsiParameter parameter, PsiType iteratedValueType) { final PsiIfStatement ifStatement = extractIfStatement(body); //stream - if (ifStatement != null && ifStatement.getElseBranch() == null && ifStatement.getThenBranch() != null && + if (ifStatement != null && InheritanceUtil.isInheritor(iteratedValueType, CommonClassNames.JAVA_UTIL_COLLECTION)) { return false; } @@ -157,11 +200,12 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo String foreEachText = body.getText(); String iterated = iteratedValue.getText(); - if (ifStmt != null && ifStmt.getElseBranch() == null) { + if (ifStmt != null) { final PsiExpression condition = ifStmt.getCondition(); if (condition != null) { final PsiStatement thenBranch = ifStmt.getThenBranch(); - if (thenBranch != null && InheritanceUtil.isInheritor(iteratedValue.getType(), CommonClassNames.JAVA_UTIL_COLLECTION)) { + LOG.assertTrue(thenBranch != null); + if (InheritanceUtil.isInheritor(iteratedValue.getType(), CommonClassNames.JAVA_UTIL_COLLECTION)) { body = thenBranch; foreEachText = thenBranch.getText(); iterated += ".stream().filter(" + parameter.getName() + " -> " + condition.getText() +")"; @@ -170,8 +214,16 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo } final PsiParameter[] parameters = {parameter}; - final PsiCallExpression expression = LambdaCanBeMethodReferenceInspection.canBeMethodReferenceProblem(body instanceof PsiBlockStatement ? ((PsiBlockStatement)body).getCodeBlock() : body, parameters, null); - final String methodReferenceText = LambdaCanBeMethodReferenceInspection.createMethodReferenceText(expression, null, parameters); + String methodReferenceText = null; + final PsiCallExpression callExpression = LambdaCanBeMethodReferenceInspection.extractMethodCallFromBlock(body); + if (callExpression != null) { + final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); + final PsiClass consumerClass = psiFacade.findClass("java.util.function.Consumer", GlobalSearchScope.allScope(project)); + final PsiClassType functionalType = consumerClass != null ? psiFacade.getElementFactory().createType(consumerClass, callExpression.getType()) : null; + + final PsiCallExpression toConvertCall = LambdaCanBeMethodReferenceInspection.canBeMethodReferenceProblem(body instanceof PsiBlockStatement ? ((PsiBlockStatement)body).getCodeBlock() : body, parameters, functionalType); + methodReferenceText = LambdaCanBeMethodReferenceInspection.createMethodReferenceText(toConvertCall, functionalType, parameters); + } final String lambdaText = parameter.getName() + " -> " + foreEachText; final String codeBlock8 = methodReferenceText != null ? methodReferenceText : lambdaText; PsiExpressionStatement callStatement = (PsiExpressionStatement)JavaPsiFacade.getElementFactory(project).createStatementFromText(iterated + ".forEach(" + codeBlock8 + ");", foreachStatement); @@ -191,6 +243,98 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo } } + private static class ReplaceWithCollectCallFix implements LocalQuickFix { + @NotNull + @Override + public String getName() { + return getFamilyName(); + } + + @NotNull + @Override + public String getFamilyName() { + return "Replace with collect"; + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + final PsiForeachStatement foreachStatement = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiForeachStatement.class); + if (foreachStatement != null) { + PsiStatement body = foreachStatement.getBody(); + final PsiExpression iteratedValue = foreachStatement.getIteratedValue(); + if (body != null && iteratedValue != null) { + final PsiParameter parameter = foreachStatement.getIterationParameter(); + + final PsiIfStatement ifStatement = extractIfStatement(body); + final PsiMethodCallExpression methodCallExpression = extractAddCall(body); + String iteration = iteratedValue.getText() + ".stream()"; + if (ifStatement != null) { + final PsiExpression condition = ifStatement.getCondition(); + if (condition != null) { + iteration += ".filter(" + parameter.getName() + " -> " + condition.getText() +")"; + } + } + iteration +=".map("; + + final PsiExpression mapperCall = methodCallExpression.getArgumentList().getExpressions()[0]; + + final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); + final PsiClass functionClass = psiFacade.findClass("java.util.function.Function", GlobalSearchScope.allScope(project)); + final PsiClassType functionalInterfaceType = functionClass != null ? psiFacade.getElementFactory().createType(functionClass, parameter.getType(), mapperCall.getType()) : null; + final PsiCallExpression toConvertCall = LambdaCanBeMethodReferenceInspection.canBeMethodReferenceProblem(mapperCall, + new PsiParameter[]{ + parameter}, + functionalInterfaceType); + final String methodReferenceText = LambdaCanBeMethodReferenceInspection.createMethodReferenceText(toConvertCall, functionalInterfaceType, new PsiParameter[]{parameter}); + if (methodReferenceText != null) { + iteration += methodReferenceText; + } else { + iteration += parameter.getName() + " -> " + mapperCall.getText(); + } + iteration += ").collect(java.util.stream.Collectors."; + + String variableName = null; + PsiExpression initializer = null; + final PsiExpression qualifierExpression = methodCallExpression.getMethodExpression().getQualifierExpression(); + if (qualifierExpression instanceof PsiReferenceExpression) { + final PsiElement resolve = ((PsiReferenceExpression)qualifierExpression).resolve(); + if (resolve instanceof PsiVariable) { + if (resolve instanceof PsiLocalVariable && foreachStatement.equals(PsiTreeUtil.skipSiblingsForward(resolve.getParent(), PsiWhiteSpace.class))) { + initializer = ((PsiVariable)resolve).getInitializer(); + } + variableName = ((PsiVariable)resolve).getName() + "."; + } + } else if (qualifierExpression == null) { + variableName = ""; + } + + PsiElement result = null; + if (initializer != null) { + final PsiType initializerType = initializer.getType(); + final PsiClassType rawType = initializerType instanceof PsiClassType ? ((PsiClassType)initializerType).rawType() : null; + if (rawType != null && rawType.equalsToText(CommonClassNames.JAVA_UTIL_ARRAY_LIST)) { + iteration += "toList()"; + } else if (rawType != null && rawType.equalsToText(CommonClassNames.JAVA_UTIL_HASH_SET)) { + iteration += "toSet()"; + } else { + iteration += "toCollection(() -> " + initializer.getText() +")"; + } + iteration += ")"; + result = initializer.replace(JavaPsiFacade.getElementFactory(project).createExpressionFromText(iteration, foreachStatement)); + foreachStatement.delete(); + } else if (variableName != null){ + iteration += "toList())"; + result = foreachStatement.replace(JavaPsiFacade.getElementFactory(project).createStatementFromText(variableName + "addAll(" + iteration +");", foreachStatement)); + } + + if (result != null) { + result = JavaCodeStyleManager.getInstance(project).shortenClassReferences(result); + } + } + } + } + } + public static PsiIfStatement extractIfStatement(PsiStatement body) { PsiIfStatement ifStmt = null; if (body instanceof PsiIfStatement) { @@ -201,6 +345,34 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo ifStmt = (PsiIfStatement)statements[0]; } } - return ifStmt; + if (ifStmt != null && ifStmt.getElseBranch() == null && ifStmt.getThenBranch() != null) { + return ifStmt; + } + return null; + } + + private static PsiMethodCallExpression extractAddCall(PsiStatement body) { + final PsiIfStatement ifStatement = extractIfStatement(body); + if (ifStatement != null) { + return extractAddCall(ifStatement.getThenBranch()); + } + PsiExpressionStatement stmt = null; + if (body instanceof PsiBlockStatement) { + final PsiStatement[] statements = ((PsiBlockStatement)body).getCodeBlock().getStatements(); + if (statements.length == 1 && statements[0] instanceof PsiExpressionStatement) { + stmt = (PsiExpressionStatement)statements[0]; + } + } + else if (body instanceof PsiExpressionStatement) { + stmt = (PsiExpressionStatement)body; + } + + if (stmt != null) { + final PsiExpression expression = stmt.getExpression(); + if (expression instanceof PsiMethodCallExpression) { + return (PsiMethodCallExpression)expression; + } + } + return null; } } 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 cc1b2ae059cd..2e15ac48f7f3 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 @@ -506,12 +506,16 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { final String text = isNullLiteralExpression(expr) ? InspectionsBundle.message("dataflow.message.return.null.from.notnullable", presentableNullable) : InspectionsBundle.message("dataflow.message.return.nullable.from.notnullable", presentableNullable); - holder.registerProblem(expr, text, new AnnotateMethodFix(defaultNullable, ArrayUtil.toStringArray(manager.getNotNulls())){ - @Override - public int shouldAnnotateBaseMethod(PsiMethod method, PsiMethod superMethod, Project project) { - return 1; - } - }); + final LocalQuickFix[] fixes = + PsiTreeUtil.skipParentsOfType(expr, PsiCodeBlock.class, PsiReturnStatement.class) instanceof PsiLambdaExpression + ? LocalQuickFix.EMPTY_ARRAY + : new LocalQuickFix[]{ new AnnotateMethodFix(defaultNullable, ArrayUtil.toStringArray(manager.getNotNulls())) { + @Override + public int shouldAnnotateBaseMethod(PsiMethod method, PsiMethod superMethod, Project project) { + return 1; + } + }}; + holder.registerProblem(expr, text, fixes); } } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java index b647e7d1b37f..f8c395ce17fd 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java @@ -81,6 +81,13 @@ public class JavaLineMarkerProvider implements LineMarkerProvider, DumbAware { } } + final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(element); + if (interfaceMethod != null) { + final Icon icon = AllIcons.Gutter.ImplementingMethod; + final MarkerType type = MarkerType.OVERRIDING_METHOD; + return new ArrowUpLineMarkerInfo(element, icon, type); + } + if (myDaemonSettings.SHOW_METHOD_SEPARATORS && element.getFirstChild() == null) { PsiElement element1 = element; boolean isMember = false; diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java index 12b1788dcea7..72e8eca35fa6 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java @@ -53,27 +53,27 @@ public class MarkerType { public static final MarkerType OVERRIDING_METHOD = new MarkerType(new NullableFunction<PsiElement, String>() { @Override public String fun(PsiElement element) { - PsiElement parent = element.getParent(); + PsiElement parent = getParentMethod(element); if (!(parent instanceof PsiMethod)) return null; PsiMethod method = (PsiMethod)parent; - return calculateOverridingMethodTooltip(method); + return calculateOverridingMethodTooltip(method, method != element.getParent()); } }, new LineMarkerNavigator(){ @Override public void browse(MouseEvent e, PsiElement element) { - PsiElement parent = element.getParent(); + PsiElement parent = getParentMethod(element); if (!(parent instanceof PsiMethod)) return; PsiMethod method = (PsiMethod)parent; - navigateToOverridingMethod(e, method); + navigateToOverridingMethod(e, method, method != element.getParent()); } }); @Nullable - public static String calculateOverridingMethodTooltip(PsiMethod method) { - PsiMethod[] superMethods = method.findSuperMethods(false); - if (superMethods.length == 0) return null; + public static String calculateOverridingMethodTooltip(PsiMethod method, boolean acceptSelf) { + PsiMethod[] superMethods = composeSuperMethods(method, acceptSelf); + if (superMethods == null) return null; PsiMethod superMethod = superMethods[0]; boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT); @@ -90,9 +90,9 @@ public class MarkerType { return GutterIconTooltipHelper.composeText(superMethods, "", DaemonBundle.message(key)); } - public static void navigateToOverridingMethod(MouseEvent e, PsiMethod method) { - PsiMethod[] superMethods = method.findSuperMethods(false); - if (superMethods.length == 0) return; + public static void navigateToOverridingMethod(MouseEvent e, PsiMethod method, boolean acceptSelf) { + PsiMethod[] superMethods = composeSuperMethods(method, acceptSelf); + if (superMethods == null) return; boolean showMethodNames = !PsiUtil.allMethodsHaveSameSignature(superMethods); PsiElementListNavigator.openTargets(e, superMethods, DaemonBundle.message("navigation.title.super.method", method.getName()), @@ -100,6 +100,22 @@ public class MarkerType { new MethodCellRenderer(showMethodNames)); } + @Nullable + private static PsiMethod[] composeSuperMethods(PsiMethod method, boolean acceptSelf) { + PsiMethod[] superMethods = method.findSuperMethods(false); + if (acceptSelf) { + superMethods = ArrayUtil.prepend(method, superMethods); + } + if (superMethods.length == 0) return null; + return superMethods; + } + + private static PsiElement getParentMethod(PsiElement element) { + final PsiElement parent = element.getParent(); + final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(element); + return interfaceMethod != null ? interfaceMethod : parent; + } + public static final String SEARCHING_FOR_OVERRIDING_METHODS = "Searching for overriding methods"; public static final MarkerType OVERRIDEN_METHOD = new MarkerType(new NullableFunction<PsiElement, String>() { @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExceptionToCatchFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExceptionToCatchFix.java index ccb1c3c369e4..5d51949c1d6b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExceptionToCatchFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExceptionToCatchFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,7 +52,9 @@ public class AddExceptionToCatchFix extends BaseIntentionAction { PsiDocumentManager.getInstance(project).commitAllDocuments(); PsiElement element = findElement(file, offset); - PsiTryStatement tryStatement = (PsiTryStatement) element.getParent(); + if (element == null) return; + + PsiTryStatement tryStatement = (PsiTryStatement)element.getParent(); List<PsiClassType> unhandledExceptions = new ArrayList<PsiClassType>(ExceptionUtil.collectUnhandledExceptions(element, null)); ExceptionUtil.sortExceptionsByHierarchy(unhandledExceptions); @@ -86,7 +88,9 @@ public class AddExceptionToCatchFix extends BaseIntentionAction { } } - private static PsiCodeBlock addCatchStatement(PsiTryStatement tryStatement, PsiClassType exceptionType, PsiFile file) throws IncorrectOperationException { + private static PsiCodeBlock addCatchStatement(PsiTryStatement tryStatement, + PsiClassType exceptionType, + PsiFile file) throws IncorrectOperationException { PsiElementFactory factory = JavaPsiFacade.getInstance(tryStatement.getProject()).getElementFactory(); if (tryStatement.getTryBlock() == null) { @@ -108,9 +112,12 @@ public class AddExceptionToCatchFix extends BaseIntentionAction { } PsiParameter[] parameters = tryStatement.getCatchBlockParameters(); - parameters[parameters.length - 1].getTypeElement().replace(factory.createTypeElement(exceptionType)); - PsiCodeBlock[] catchBlocks = tryStatement.getCatchBlocks(); + PsiTypeElement typeElement = parameters[parameters.length - 1].getTypeElement(); + if (typeElement != null) { + JavaCodeStyleManager.getInstance(file.getProject()).shortenClassReferences(typeElement); + } + PsiCodeBlock[] catchBlocks = tryStatement.getCatchBlocks(); return catchBlocks[catchBlocks.length - 1]; } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodFix.java index 19a4639a0689..69800e5616f7 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodFix.java @@ -200,7 +200,7 @@ public class StaticImportMethodFix implements IntentionAction { //do not show methods from default package && !((PsiJavaFile)file).getPackageName().isEmpty() && PsiUtil.isAccessible(file.getProject(), method, element, containingClass)) { - if (method.isDeprecated()) { + if (isEffectivelyDeprecated(method)) { deprecated.put(containingClass, method); return processCondition(); } @@ -209,6 +209,20 @@ public class StaticImportMethodFix implements IntentionAction { return processCondition(); } + private boolean isEffectivelyDeprecated(PsiMethod method) { + if (method.isDeprecated()) { + return true; + } + PsiClass aClass = method.getContainingClass(); + while (aClass != null) { + if (aClass.isDeprecated()) { + return true; + } + aClass = aClass.getContainingClass(); + } + return false; + } + private boolean processCondition() { return (applicableList.isEmpty() ? list : applicableList).size() + deprecated.size() < 50; } diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java index e72756865767..0d822feff94c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java @@ -21,7 +21,6 @@ import com.intellij.openapi.project.DumbAware; import com.intellij.psi.*; import com.intellij.psi.util.PsiUtil; import com.intellij.util.text.CharArrayUtil; -import com.intellij.xml.util.XmlStringUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -119,9 +118,9 @@ public class AnnotationParameterInfoHandler implements ParameterInfoHandler<PsiA @NonNls StringBuilder buffer = new StringBuilder(); buffer.append(p.getReturnType().getPresentableText()); buffer.append(" "); - int highlightStartOffset = XmlStringUtil.escapeString(buffer.toString()).length(); + int highlightStartOffset = buffer.length(); buffer.append(p.getName()); - int highlightEndOffset = XmlStringUtil.escapeString(buffer.toString()).length(); + int highlightEndOffset = buffer.length(); buffer.append("()"); if (p.getDefaultValue() != null) { 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 5da27d9c18d3..b3918fd0fbe2 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 @@ -32,7 +32,6 @@ import com.intellij.psi.util.MethodSignatureUtil; import com.intellij.psi.util.PsiUtilBase; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.HashSet; -import com.intellij.xml.util.XmlStringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -393,7 +392,7 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc for (int j = 0; j < numParams; j++) { PsiParameter param = parms[j]; - int startOffset = XmlStringUtil.escapeString(buffer.toString()).length(); + int startOffset = buffer.length(); if (param.isValid()) { PsiType paramType = param.getType(); @@ -411,7 +410,7 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc } } - int endOffset = XmlStringUtil.escapeString(buffer.toString()).length(); + int endOffset = buffer.length(); if (j < numParams - 1) { buffer.append(", "); diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddAnnotationIntention.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddAnnotationIntention.java index 2b839b5dfcde..daf5aa5eac74 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddAnnotationIntention.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddAnnotationIntention.java @@ -26,13 +26,11 @@ import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.intention.AddAnnotationFix; import com.intellij.codeInsight.intention.AddAnnotationPsiFix; -import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; -import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -49,22 +47,11 @@ public abstract class AddAnnotationIntention extends BaseIntentionAction { // include not in project files @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - CaretModel caretModel = editor.getCaretModel(); - int position = caretModel.getOffset(); - PsiElement element = file.findElementAt(position); - return element != null && isAvailable(project, element); - } - - public boolean isAvailable(@NotNull final Project project, @NotNull final PsiElement element) { - if (!element.isValid()) return false; - final PsiModifierListOwner owner; - if (!element.getManager().isInProject(element) || CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS) { - owner = AddAnnotationPsiFix.getContainer(element); - } - else { + final PsiModifierListOwner owner = AddAnnotationPsiFix.getContainer(file, editor.getCaretModel().getOffset()); + if (owner == null || + owner.getManager().isInProject(owner) && !CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS) { return false; } - if (owner == null) return false; Pair<String, String[]> annotations = getAnnotations(project); String toAdd = annotations.first; String[] toRemove = annotations.second; @@ -82,11 +69,7 @@ public abstract class AddAnnotationIntention extends BaseIntentionAction { @Override public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - CaretModel caretModel = editor.getCaretModel(); - int position = caretModel.getOffset(); - PsiElement element = file.findElementAt(position); - - PsiModifierListOwner owner = AddAnnotationPsiFix.getContainer(element); + PsiModifierListOwner owner = AddAnnotationPsiFix.getContainer(file, editor.getCaretModel().getOffset()); if (owner == null || !owner.isValid()) return; Pair<String, String[]> annotations = getAnnotations(project); String toAdd = annotations.first; diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseColorIntentionAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseColorIntentionAction.java index adde45b86af6..f3c9df9dfe16 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseColorIntentionAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseColorIntentionAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,9 +28,11 @@ import static com.intellij.patterns.PlatformPatterns.psiElement; /** * @author Danila Ponomarenko + * @author Konstantin Bulenkov */ public abstract class BaseColorIntentionAction extends PsiElementBaseIntentionAction implements HighPriorityAction { protected static final String JAVA_AWT_COLOR = "java.awt.Color"; + protected static final String COLOR_UI_RESOURCE = "javax.swing.plaf.ColorUIResource"; @Override public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) { @@ -39,29 +41,28 @@ public abstract class BaseColorIntentionAction extends PsiElementBaseIntentionAc } final PsiNewExpression expression = PsiTreeUtil.getParentOfType(element, PsiNewExpression.class, false); - if (expression == null) { - return false; - } - - return isJavaAwtColor(expression.getClassOrAnonymousClassReference()) && isValueArguments(expression.getArgumentList()); + return expression != null + && isJavaAwtColor(expression.getClassOrAnonymousClassReference()) + && isValueArguments(expression.getArgumentList()); } private static boolean isJavaAwtColor(@Nullable PsiJavaCodeReferenceElement ref) { - if (ref == null) { - return false; - } - - final PsiReference reference = ref.getReference(); - if (reference == null) { - return false; - } + final String fqn = getFqn(ref); + return JAVA_AWT_COLOR.equals(fqn) || COLOR_UI_RESOURCE.equals(fqn); + } - final PsiElement psiElement = reference.resolve(); - if (psiElement instanceof PsiClass && JAVA_AWT_COLOR.equals(((PsiClass)psiElement).getQualifiedName())) { - return true; + @Nullable + protected static String getFqn(@Nullable PsiJavaCodeReferenceElement ref) { + if (ref != null) { + final PsiReference reference = ref.getReference(); + if (reference != null) { + final PsiElement psiElement = reference.resolve(); + if (psiElement instanceof PsiClass) { + return ((PsiClass)psiElement).getQualifiedName(); + } + } } - - return false; + return null; } private static boolean isValueArguments(@Nullable PsiExpressionList arguments) { diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ColorChooserIntentionAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ColorChooserIntentionAction.java index db93d4e851f5..f5d1b3a28afe 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ColorChooserIntentionAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ColorChooserIntentionAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -191,7 +191,7 @@ public class ColorChooserIntentionAction extends BaseColorIntentionAction { final PsiManager manager = expression.getManager(); final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); final PsiExpression newCall = factory.createExpressionFromText( - "new " + JAVA_AWT_COLOR + "(" + "new " + getFqn(expression.getClassOrAnonymousClassReference()) + "(" + color.getRed() + ", " + color.getGreen() + ", " + color.getBlue() diff --git a/java/java-impl/src/com/intellij/codeInsight/navigation/JavaGotoSuperHandler.java b/java/java-impl/src/com/intellij/codeInsight/navigation/JavaGotoSuperHandler.java index 94ddb7ae863e..55d82a987001 100644 --- a/java/java-impl/src/com/intellij/codeInsight/navigation/JavaGotoSuperHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/navigation/JavaGotoSuperHandler.java @@ -30,6 +30,7 @@ import com.intellij.psi.*; import com.intellij.psi.impl.FindSuperElementsHelper; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; +import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -65,20 +66,27 @@ public class JavaGotoSuperHandler implements CodeInsightActionHandler { @Nullable private PsiElement[] findSuperElements(PsiFile file, int offset) { - PsiNameIdentifierOwner parent = getElement(file, offset); - if (parent == null) return null; + PsiElement element = getElement(file, offset); + if (element == null) return null; + + final PsiExpression expression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class, PsiMethodReferenceExpression.class); + if (expression != null) { + final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(expression); + if (interfaceMethod != null) { + return ArrayUtil.prepend(interfaceMethod, interfaceMethod.findSuperMethods(false)); + } + } + + final PsiNameIdentifierOwner parent = PsiTreeUtil.getNonStrictParentOfType(element, PsiMethod.class, PsiClass.class); + if (parent == null) { + return null; + } return FindSuperElementsHelper.findSuperElements(parent); } - protected PsiNameIdentifierOwner getElement(PsiFile file, int offset) { - PsiElement element = file.findElementAt(offset); - if (element == null) return null; - - PsiNameIdentifierOwner parent = PsiTreeUtil.getParentOfType(element, PsiMethod.class, PsiClass.class); - if (parent == null) - return null; - return parent; + protected PsiElement getElement(PsiFile file, int offset) { + return file.findElementAt(offset); } @Override diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java index 7040347c4d0e..767077b3448e 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java @@ -28,7 +28,6 @@ import com.intellij.openapi.ui.InputValidatorEx; import com.intellij.openapi.ui.Messages; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; -import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -48,22 +47,15 @@ public class EditContractIntention extends BaseIntentionAction { @Nullable private static PsiMethod getTargetMethod(@NotNull Project project, Editor editor, PsiFile file) { - PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); - if (element == null) return null; - if (!element.getManager().isInProject(element) || CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS) { - final PsiModifierListOwner owner = AddAnnotationPsiFix.getContainer(element); - if (owner instanceof PsiMethod) { - PsiElement original = owner.getOriginalElement(); - if (original instanceof PsiMethod) { - return (PsiMethod)original; - } - return (PsiMethod)owner; - } + final PsiModifierListOwner owner = AddAnnotationPsiFix.getContainer(file, editor.getCaretModel().getOffset()); + if (owner instanceof PsiMethod && + (!owner.getManager().isInProject(owner) || CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS)) { + PsiElement original = owner.getOriginalElement(); + return original instanceof PsiMethod ? (PsiMethod)original : (PsiMethod)owner; } return null; } - @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { final PsiMethod method = getTargetMethod(project, editor, file); diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaReferenceAdjuster.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaReferenceAdjuster.java index db020ad58b8b..42d3098b7b07 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaReferenceAdjuster.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaReferenceAdjuster.java @@ -60,6 +60,12 @@ public class JavaReferenceAdjuster implements ReferenceAdjuster { } if (rightKind) { + // annotations may jump out of reference (see PsiJavaCodeReferenceImpl#setAnnotations()) so they should be processed first + List<PsiAnnotation> annotations = PsiTreeUtil.getChildrenOfTypeAsList(ref, PsiAnnotation.class); + for (PsiAnnotation annotation : annotations) { + process(annotation.getNode(), addImports, incompleteCode, useFqInJavadoc, useFqInCode); + } + boolean isInsideDocComment = TreeUtil.findParent(element, JavaDocElementType.DOC_COMMENT) != null; boolean isShort = !ref.isQualified(); if (isInsideDocComment ? !useFqInJavadoc : !useFqInCode) { diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceSet.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceSet.java index c184775ad11b..dbcbfdc4e546 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceSet.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceSet.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; import com.intellij.psi.util.PsiUtil; import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -44,27 +45,29 @@ public class JavaClassReferenceSet { private final int myStartInElement; private final JavaClassReferenceProvider myProvider; - public JavaClassReferenceSet(String str, PsiElement element, int startInElement, final boolean isStatic, JavaClassReferenceProvider provider) { + public JavaClassReferenceSet(@NotNull String str, @NotNull PsiElement element, int startInElement, final boolean isStatic, @NotNull JavaClassReferenceProvider provider) { this(str, element, startInElement, isStatic, provider, null); } - private JavaClassReferenceSet(String str, PsiElement element, int startInElement, final boolean isStatic, JavaClassReferenceProvider provider, + private JavaClassReferenceSet(@NotNull String str, @NotNull PsiElement element, int startInElement, final boolean isStatic, @NotNull JavaClassReferenceProvider provider, JavaClassReferenceSet context) { myStartInElement = startInElement; myProvider = provider; reparse(str, element, isStatic, context); } + @NotNull public JavaClassReferenceProvider getProvider() { return myProvider; } + @NotNull public TextRange getRangeInElement() { PsiReference[] references = getReferences(); return new TextRange(references[0].getRangeInElement().getStartOffset(), references[references.length - 1].getRangeInElement().getEndOffset()); } - private void reparse(String str, PsiElement element, final boolean isStaticImport, JavaClassReferenceSet context) { + private void reparse(@NotNull String str, @NotNull PsiElement element, final boolean isStaticImport, JavaClassReferenceSet context) { myElement = element; myContext = context; final List<JavaClassReference> referencesList = new ArrayList<JavaClassReference>(); @@ -186,7 +189,8 @@ public class JavaClassReferenceSet { myReferences = referencesList.toArray(new JavaClassReference[referencesList.size()]); } - protected JavaClassReference createReference(final int referenceIndex, final String subreferenceText, final TextRange textRange, + @NotNull + protected JavaClassReference createReference(final int referenceIndex, @NotNull String subreferenceText, @NotNull TextRange textRange, final boolean staticImport) { return new JavaClassReference(this, textRange, referenceIndex, subreferenceText, staticImport); } @@ -200,7 +204,7 @@ public class JavaClassReferenceSet { return isAllowDollarInNames() ? c == DOLLAR : c == DOT; } - public void reparse(PsiElement element, final TextRange range) { + public void reparse(@NotNull PsiElement element, @NotNull TextRange range) { final String text = range.substring(element.getText()); reparse(text, element, false, myContext); } @@ -209,6 +213,7 @@ public class JavaClassReferenceSet { return myReferences[index]; } + @NotNull public JavaClassReference[] getAllReferences() { JavaClassReference[] result = myReferences; if (myNestedGenericParameterReferences != null) { @@ -229,10 +234,12 @@ public class JavaClassReferenceSet { return myProvider.isSoft(); } + @NotNull public PsiElement getElement() { return myElement; } + @NotNull public PsiReference[] getReferences() { return myReferences; } @@ -243,6 +250,7 @@ public class JavaClassReferenceSet { } @SuppressWarnings({"UnresolvedPropertyKey"}) + @NotNull public String getUnresolvedMessagePattern(int index){ if (canReferencePackage(index)) { return JavaErrorMessages.message("error.cannot.resolve.class.or.package"); 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 ee207fb89fc7..a32dc464f7fa 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiUtil; @@ -187,27 +188,28 @@ public class ChangeClassSignatureProcessor extends BaseRefactoringProcessor { ChangeSignatureUtil.synchronizeList(myClass.getTypeParameterList(), newTypeParameters, TypeParameterList.INSTANCE, toRemoveParms); } - private boolean[] detectRemovedParameters(final PsiTypeParameter[] originaltypeParameters) { - final boolean[] toRemoveParms = new boolean[originaltypeParameters.length]; - Arrays.fill(toRemoveParms, true); + private boolean[] detectRemovedParameters(final PsiTypeParameter[] original) { + final boolean[] toRemove = new boolean[original.length]; + Arrays.fill(toRemove, true); for (final TypeParameterInfo info : myNewSignature) { int oldParameterIndex = info.getOldParameterIndex(); if (oldParameterIndex >= 0) { - toRemoveParms[oldParameterIndex] = false; + toRemove[oldParameterIndex] = false; } } - return toRemoveParms; + return toRemove; } - private void processUsage(final UsageInfo usage, final PsiTypeParameter[] originalTypeParameters, final boolean[] toRemoveParms) - throws IncorrectOperationException { + private void processUsage(UsageInfo usage, PsiTypeParameter[] original, boolean[] toRemove) throws IncorrectOperationException { PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory(); PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)usage.getElement(); + assert referenceElement != null : usage; PsiSubstitutor usageSubstitutor = determineUsageSubstitutor(referenceElement); PsiReferenceParameterList referenceParameterList = referenceElement.getParameterList(); + assert referenceParameterList != null : referenceElement; PsiTypeElement[] oldValues = referenceParameterList.getTypeParameterElements(); - if (oldValues.length != originalTypeParameters.length) return; + if (oldValues.length != original.length) return; List<PsiTypeElement> newValues = new ArrayList<PsiTypeElement>(); for (final TypeParameterInfo info : myNewSignature) { int oldIndex = info.getOldParameterIndex(); @@ -221,7 +223,9 @@ public class ChangeClassSignatureProcessor extends BaseRefactoringProcessor { newValues.add(newValue); } } - ChangeSignatureUtil.synchronizeList(referenceParameterList, newValues, ReferenceParameterList.INSTANCE, toRemoveParms); + + ChangeSignatureUtil.synchronizeList(referenceParameterList, newValues, ReferenceParameterList.INSTANCE, toRemove); + JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(referenceParameterList); } private PsiSubstitutor determineUsageSubstitutor(PsiJavaCodeReferenceElement referenceElement) { diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/ParameterInfoImpl.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/ParameterInfoImpl.java index aa27a6e024ca..69fc99031e80 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/ParameterInfoImpl.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/ParameterInfoImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,11 +33,13 @@ import java.util.ArrayList; import java.util.List; public class ParameterInfoImpl implements JavaParameterInfo { + public static final ParameterInfoImpl[] EMPTY_ARRAY = {}; + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.ParameterInfoImpl"); + public int oldParameterIndex; - boolean useAnySingleVariable; + private boolean useAnySingleVariable; private String name = ""; - public static final ParameterInfoImpl[] EMPTY_ARRAY = new ParameterInfoImpl[0]; private CanonicalTypes.Type myType; String defaultValue = ""; diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineToAnonymousClassProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineToAnonymousClassProcessor.java index 25a9481259d8..2b483ddb676c 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineToAnonymousClassProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineToAnonymousClassProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; import com.intellij.openapi.wm.WindowManager; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiTreeUtil; @@ -259,9 +260,13 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor { new InlineToAnonymousConstructorProcessor(myClass, psiNewExpression, superType).run(); } else { - PsiJavaCodeReferenceElement element = - JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory().createClassReferenceElement(superType.resolve()); - psiNewExpression.getClassReference().replace(element); + PsiClass target = superType.resolve(); + assert target != null : superType; + PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory(); + PsiJavaCodeReferenceElement element = factory.createClassReferenceElement(target); + PsiJavaCodeReferenceElement reference = psiNewExpression.getClassReference(); + assert reference != null : psiNewExpression; + reference.replace(element); } } catch (IncorrectOperationException e) { @@ -276,7 +281,8 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor { PsiType substType = classResolveResult.getSubstitutor().substitute(superType); assert classResolveResult.getElement() == myClass; try { - typeElement.replace(factory.createTypeElement(substType)); + PsiElement replaced = typeElement.replace(factory.createTypeElement(substType)); + JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(replaced); } catch(IncorrectOperationException e) { LOG.error(e); diff --git a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/usageInfo/ReplaceWithSubtypeUsageInfo.java b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/usageInfo/ReplaceWithSubtypeUsageInfo.java index f2a6a2e647a2..ec1e10df935b 100644 --- a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/usageInfo/ReplaceWithSubtypeUsageInfo.java +++ b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/usageInfo/ReplaceWithSubtypeUsageInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,21 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/* - * User: anna - * Date: 27-Aug-2008 - */ package com.intellij.refactoring.inlineSuperClass.usageInfo; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.util.FixableUsageInfo; import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; +/** + * @author anna + * @since 27-Aug-2008 + */ public class ReplaceWithSubtypeUsageInfo extends FixableUsageInfo { public static final Logger LOG = Logger.getInstance("#" + ReplaceWithSubtypeUsageInfo.class.getName()); private final PsiTypeElement myTypeElement; @@ -51,8 +52,10 @@ public class ReplaceWithSubtypeUsageInfo extends FixableUsageInfo { public void fixUsage() throws IncorrectOperationException { if (myTypeElement.isValid()) { - final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(myTypeElement.getProject()).getElementFactory(); - myTypeElement.replace(elementFactory.createTypeElement(myTargetClassType)); + Project project = myTypeElement.getProject(); + PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory(); + PsiElement replaced = myTypeElement.replace(elementFactory.createTypeElement(myTargetClassType)); + JavaCodeStyleManager.getInstance(project).shortenClassReferences(replaced); } } diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java index 6d333e9cb54b..3e92a19373ab 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java @@ -23,6 +23,7 @@ package com.intellij.refactoring.move.moveClassesOrPackages; import com.intellij.history.LocalHistory; import com.intellij.history.LocalHistoryAction; import com.intellij.ide.util.DirectoryChooser; +import com.intellij.ide.util.PlatformPackageUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.diagnostic.Logger; @@ -266,7 +267,8 @@ public class MoveClassesOrPackagesImpl { return aPackage != null ? getTargetPackageNameForMovedElement(aPackage) : ""; } else if (psiElement != null) { - PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(psiElement.getContainingFile().getContainingDirectory()); + PsiDirectory directory = PlatformPackageUtil.getDirectory(psiElement); + PsiPackage aPackage = directory == null ? null : JavaDirectoryService.getInstance().getPackage(directory); return aPackage != null ? aPackage.getQualifiedName() : ""; } else { diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationReplacementUtil.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationReplacementUtil.java index f6cdabacedad..0004ff456cb6 100644 --- a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationReplacementUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationReplacementUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package com.intellij.refactoring.typeMigration; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.impl.PsiDiamondTypeUtil; import com.intellij.psi.impl.source.tree.ChildRole; import com.intellij.psi.impl.source.tree.CompositeElement; @@ -109,18 +110,19 @@ public class TypeMigrationReplacementUtil { if (!migratedType.isValid()) { migratedType = JavaPsiFacade.getElementFactory(project).createTypeByFQClassName(migratedType.getCanonicalText()); } - final PsiTypeElement typeElement = - JavaPsiFacade.getInstance(project).getElementFactory().createTypeElement(migratedType); + final PsiTypeElement typeElement = JavaPsiFacade.getInstance(project).getElementFactory().createTypeElement(migratedType); if (element instanceof PsiMethod) { final PsiTypeElement returnTypeElement = ((PsiMethod)element).getReturnTypeElement(); if (returnTypeElement != null) { - returnTypeElement.replace(typeElement); + final PsiElement replaced = returnTypeElement.replace(typeElement); + JavaCodeStyleManager.getInstance(project).shortenClassReferences(replaced); } } else if (element instanceof PsiVariable) { final PsiTypeElement varTypeElement = ((PsiVariable)element).getTypeElement(); if (varTypeElement != null) { - varTypeElement.replace(typeElement); + final PsiElement replaced = varTypeElement.replace(typeElement); + JavaCodeStyleManager.getInstance(project).shortenClassReferences(replaced); } } else { diff --git a/java/java-impl/src/com/intellij/spi/SPIGotoSuperHandler.java b/java/java-impl/src/com/intellij/spi/SPIGotoSuperHandler.java index 04c48bc71e40..966a7a3422ea 100644 --- a/java/java-impl/src/com/intellij/spi/SPIGotoSuperHandler.java +++ b/java/java-impl/src/com/intellij/spi/SPIGotoSuperHandler.java @@ -16,9 +16,8 @@ package com.intellij.spi; import com.intellij.codeInsight.navigation.JavaGotoSuperHandler; -import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiNameIdentifierOwner; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.spi.psi.SPIClassProviderReferenceElement; @@ -27,11 +26,11 @@ import com.intellij.spi.psi.SPIClassProviderReferenceElement; */ public class SPIGotoSuperHandler extends JavaGotoSuperHandler { @Override - protected PsiNameIdentifierOwner getElement(PsiFile file, int offset) { + protected PsiElement getElement(PsiFile file, int offset) { final SPIClassProviderReferenceElement - providerElement = PsiTreeUtil.getParentOfType(file.findElementAt(offset), SPIClassProviderReferenceElement.class); + providerElement = PsiTreeUtil.getParentOfType(super.getElement(file, offset), SPIClassProviderReferenceElement.class); if (providerElement != null) { - return (PsiClass)providerElement.resolve(); + return providerElement.resolve(); } return null; diff --git a/java/java-impl/src/com/intellij/util/xml/CanonicalPsiTypeConverterImpl.java b/java/java-impl/src/com/intellij/util/xml/CanonicalPsiTypeConverterImpl.java index 877d27453b1b..254dc036547c 100644 --- a/java/java-impl/src/com/intellij/util/xml/CanonicalPsiTypeConverterImpl.java +++ b/java/java-impl/src/com/intellij/util/xml/CanonicalPsiTypeConverterImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -80,7 +80,8 @@ public class CanonicalPsiTypeConverterImpl extends CanonicalPsiTypeConverter imp final boolean isPrimitiveType = type instanceof PsiPrimitiveType; return new JavaClassReferenceSet(trimmed, element, offset, false, CLASS_REFERENCE_PROVIDER) { - protected JavaClassReference createReference(int refIndex, String subRefText, TextRange textRange, boolean staticImport) { + @NotNull + protected JavaClassReference createReference(int refIndex, @NotNull String subRefText, @NotNull TextRange textRange, boolean staticImport) { return new JavaClassReference(this, textRange, refIndex, subRefText, staticImport) { public boolean isSoft() { return true; diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaSourceFilterScope.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaSourceFilterScope.java index 59c7d6505859..b25f8c50911f 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaSourceFilterScope.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaSourceFilterScope.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ package com.intellij.psi.impl.search; import com.intellij.ide.highlighter.JavaClassFileType; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.JdkOrderEntry; import com.intellij.openapi.roots.OrderEntry; @@ -30,13 +31,25 @@ import com.intellij.psi.SdkResolveScopeProvider; import com.intellij.psi.search.DelegatingGlobalSearchScope; import com.intellij.psi.search.GlobalSearchScope; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class JavaSourceFilterScope extends DelegatingGlobalSearchScope { + private static final Logger LOG = Logger.getInstance(JavaSourceFilterScope.class); + + @Nullable private final ProjectFileIndex myIndex; public JavaSourceFilterScope(@NotNull final GlobalSearchScope delegate) { super(delegate); - myIndex = ProjectRootManager.getInstance(getProject()).getFileIndex(); + + Project project = getProject(); + if (project != null) { + myIndex = ProjectRootManager.getInstance(project).getFileIndex(); + } + else { + myIndex = null; + LOG.error("delegate.getProject() == null, delegate.getClass() == " + delegate.getClass()); + } } @Override @@ -45,6 +58,10 @@ public class JavaSourceFilterScope extends DelegatingGlobalSearchScope { return false; } + if (myIndex == null) { + return false; + } + if (JavaClassFileType.INSTANCE == file.getFileType()) { return myIndex.isInLibraryClasses(file); } diff --git a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java index 8c36cfae1b88..577d38a30a15 100644 --- a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java @@ -519,6 +519,14 @@ public class GenericsUtil { else if (type instanceof PsiArrayType) { return checkNotAssignable(bound, type, true); } + else if (type instanceof PsiIntersectionType) { + for (PsiType psiType : ((PsiIntersectionType)type).getConjuncts()) { + if (!checkNotInBounds(psiType, bound, uncheckedConversionByDefault)) { + return false; + } + } + return true; + } return false; } 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 15b3208b7426..54bd0241e64e 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -60,6 +60,16 @@ public class LambdaUtil { return getFunctionalInterfaceMethod(PsiUtil.resolveGenericsClassInType(functionalInterfaceType)); } + public static PsiMethod getFunctionalInterfaceMethod(@Nullable PsiElement element) { + if (element instanceof PsiLambdaExpression || element instanceof PsiMethodReferenceExpression) { + final PsiType samType = element instanceof PsiLambdaExpression + ? ((PsiLambdaExpression)element).getFunctionalInterfaceType() + : ((PsiMethodReferenceExpression)element).getFunctionalInterfaceType(); + return getFunctionalInterfaceMethod(samType); + } + return null; + } + @Nullable public static PsiMethod getFunctionalInterfaceMethod(PsiClassType.ClassResolveResult result) { final PsiClass psiClass = result.getElement(); @@ -308,7 +318,7 @@ public class LambdaUtil { final int finalLambdaIdx = adjustLambdaIdx(lambdaIdx, (PsiMethod)resolve, parameters); if (finalLambdaIdx < parameters.length) { if (!tryToSubstitute) return getNormalizedType(parameters[finalLambdaIdx]); - return PsiResolveHelper.ourGuard.doPreventingRecursion(expression, true, new Computable<PsiType>() { + return PsiResolveHelper.ourGraphGuard.doPreventingRecursion(expression, true, new Computable<PsiType>() { @Override public PsiType compute() { return resolveResult.getSubstitutor().substitute(getNormalizedType(parameters[finalLambdaIdx])); diff --git a/java/java-psi-api/src/com/intellij/psi/PsiArrayType.java b/java/java-psi-api/src/com/intellij/psi/PsiArrayType.java index bc61565bdc6c..47bd7be64c65 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiArrayType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiArrayType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package com.intellij.psi; import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; /** @@ -24,7 +23,7 @@ import org.jetbrains.annotations.NotNull; * * @author max */ -public class PsiArrayType extends PsiType { +public class PsiArrayType extends PsiType.Stub { private final PsiType myComponentType; /** @@ -44,19 +43,33 @@ public class PsiArrayType extends PsiType { @NotNull @Override public String getPresentableText() { - return StringUtil.join(myComponentType.getPresentableText(), getAnnotationsTextPrefix(false, true, true), "[]"); + return getText(myComponentType.getPresentableText(), "[]", false, true); } @NotNull @Override - public String getCanonicalText() { - return StringUtil.join(myComponentType.getCanonicalText(), "[]"); + public String getCanonicalText(boolean annotated) { + return getText(myComponentType.getCanonicalText(annotated), "[]", true, annotated); } @NotNull @Override public String getInternalCanonicalText() { - return StringUtil.join(myComponentType.getInternalCanonicalText(), getAnnotationsTextPrefix(true, true, true), "[]"); + return getText(myComponentType.getInternalCanonicalText(), "[]", true, true); + } + + protected String getText(@NotNull String prefix, @NotNull String suffix, boolean qualified, boolean annotated) { + StringBuilder sb = new StringBuilder(prefix.length() + suffix.length()); + sb.append(prefix); + if (annotated) { + PsiAnnotation[] annotations = getAnnotations(); + if (annotations.length != 0) { + sb.append(' '); + PsiNameHelper.appendAnnotations(sb, annotations, qualified); + } + } + sb.append(suffix); + return sb.toString(); } @Override diff --git a/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java b/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java index 6de8d0202bef..8130b864ad9a 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java @@ -23,7 +23,7 @@ import org.jetbrains.annotations.Nullable; /** * @author ven */ -public class PsiCapturedWildcardType extends PsiType { +public class PsiCapturedWildcardType extends PsiType.Stub { @NotNull private final PsiWildcardType myExistential; @NotNull private final PsiElement myContext; @Nullable private final PsiTypeParameter myParameter; @@ -78,8 +78,8 @@ public class PsiCapturedWildcardType extends PsiType { @NotNull @Override - public String getCanonicalText() { - return myExistential.getCanonicalText(); + public String getCanonicalText(boolean annotated) { + return myExistential.getCanonicalText(annotated); } @NotNull diff --git a/java/java-psi-api/src/com/intellij/psi/PsiClassType.java b/java/java-psi-api/src/com/intellij/psi/PsiClassType.java index 30d9570048a7..722b9e2816a2 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiClassType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiClassType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -280,4 +280,23 @@ public abstract class PsiClassType extends PsiType { } }; } + + /** + * Temporary class to facilitate transition to {@link #getCanonicalText(boolean)}. + */ + public static abstract class Stub extends PsiClassType { + protected Stub(LanguageLevel languageLevel, @NotNull PsiAnnotation[] annotations) { + super(languageLevel, annotations); + } + + @NotNull + @Override + public final String getCanonicalText() { + return getCanonicalText(false); + } + + @NotNull + @Override + public abstract String getCanonicalText(boolean annotated); + } } diff --git a/java/java-psi-api/src/com/intellij/psi/PsiDisjunctionType.java b/java/java-psi-api/src/com/intellij/psi/PsiDisjunctionType.java index e9e0cf3116c4..1a4062e294fe 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiDisjunctionType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiDisjunctionType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +33,7 @@ import java.util.List; * Composite type resulting from Project Coin's multi-catch statements, i.e. <code>FileNotFoundException | EOFException</code>. * In most cases should be threatened via its least upper bound (<code>IOException</code> in the example above). */ -public class PsiDisjunctionType extends PsiType { +public class PsiDisjunctionType extends PsiType.Stub { private final PsiManager myManager; private final List<PsiType> myTypes; private final CachedValue<PsiType> myLubCache; @@ -85,15 +85,21 @@ public class PsiDisjunctionType extends PsiType { @Override public String getPresentableText() { return StringUtil.join(myTypes, new Function<PsiType, String>() { - @Override public String fun(PsiType psiType) { return psiType.getPresentableText(); } + @Override + public String fun(PsiType psiType) { + return psiType.getPresentableText(); + } }, " | "); } @NotNull @Override - public String getCanonicalText() { + public String getCanonicalText(final boolean annotated) { return StringUtil.join(myTypes, new Function<PsiType, String>() { - @Override public String fun(PsiType psiType) { return psiType.getCanonicalText(); } + @Override + public String fun(PsiType psiType) { + return psiType.getCanonicalText(annotated); + } }, " | "); } @@ -101,7 +107,10 @@ public class PsiDisjunctionType extends PsiType { @Override public String getInternalCanonicalText() { return StringUtil.join(myTypes, new Function<PsiType, String>() { - @Override public String fun(PsiType psiType) { return psiType.getInternalCanonicalText(); } + @Override + public String fun(PsiType psiType) { + return psiType.getInternalCanonicalText(); + } }, " | "); } diff --git a/java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.java b/java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.java index 0d1447924d83..085854f51a65 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,6 @@ */ package com.intellij.psi; -import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; /** @@ -45,19 +44,19 @@ public class PsiEllipsisType extends PsiArrayType { @NotNull @Override public String getPresentableText() { - return StringUtil.join(getComponentType().getPresentableText(), getAnnotationsTextPrefix(false, true, true), "..."); + return getText(getComponentType().getPresentableText(), "...", false, true); } @NotNull @Override - public String getCanonicalText() { - return StringUtil.join(getComponentType().getCanonicalText(), "..."); + public String getCanonicalText(boolean annotated) { + return getText(getComponentType().getCanonicalText(annotated), "...", true, annotated); } @NotNull @Override public String getInternalCanonicalText() { - return StringUtil.join(getComponentType().getInternalCanonicalText(), getAnnotationsTextPrefix(true, true, true), "..."); + return getText(getComponentType().getInternalCanonicalText(), "...", true, true); } @Override diff --git a/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java b/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java index 215bb86b2b81..55a5e9d55260 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ import java.util.*; * * @author ven */ -public class PsiIntersectionType extends PsiType { +public class PsiIntersectionType extends PsiType.Stub { private final PsiType[] myConjuncts; private PsiIntersectionType(@NotNull PsiType[] conjuncts) { @@ -78,7 +78,8 @@ public class PsiIntersectionType extends PsiType { for (PsiType existing : array) { if (type != existing) { final boolean allowUncheckedConversion = type instanceof PsiClassType && ((PsiClassType)type).isRaw(); - if (TypeConversionUtil.isAssignable(type, existing, allowUncheckedConversion)) { + if (TypeConversionUtil.isAssignable(GenericsUtil.eliminateWildcards(type), + GenericsUtil.eliminateWildcards(existing), allowUncheckedConversion)) { iterator.remove(); break; } @@ -110,19 +111,19 @@ public class PsiIntersectionType extends PsiType { @NotNull @Override - public String getCanonicalText() { - return myConjuncts[0].getCanonicalText(); + public String getCanonicalText(boolean annotated) { + return myConjuncts[0].getCanonicalText(annotated); } @NotNull @Override public String getInternalCanonicalText() { - StringBuilder buffer = new StringBuilder(); - for (int i = 0; i < myConjuncts.length; i++) { - buffer.append(myConjuncts[i].getInternalCanonicalText()); - if (i < myConjuncts.length - 1) buffer.append(" & "); - } - return buffer.toString(); + return StringUtil.join(myConjuncts, new Function<PsiType, String>() { + @Override + public String fun(PsiType psiType) { + return psiType.getInternalCanonicalText(); + } + }, " & "); } @Override diff --git a/java/java-psi-api/src/com/intellij/psi/PsiNameHelper.java b/java/java-psi-api/src/com/intellij/psi/PsiNameHelper.java index 6ae0fa6a081f..6e5e6563dc3b 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiNameHelper.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiNameHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,8 +23,11 @@ import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; +import java.util.List; import java.util.regex.Pattern; +import static com.intellij.util.ObjectUtils.assertNotNull; import static com.intellij.util.ObjectUtils.notNull; /** @@ -37,7 +40,7 @@ public abstract class PsiNameHelper { public static PsiNameHelper getInstance(Project project) { return ServiceManager.getService(project, PsiNameHelper.class); } - + /** * Checks if the specified text is a Java identifier, using the language level of the project * with which the name helper is associated to filter out keywords. @@ -121,30 +124,15 @@ public abstract class PsiNameHelper { } @NotNull - public static String getPresentableText(@Nullable String refName, @NotNull PsiAnnotation[] annotations, @NotNull PsiType[] typeParameters) { - if (typeParameters.length == 0 && annotations.length == 0) { + public static String getPresentableText(@Nullable String refName, @NotNull PsiAnnotation[] annotations, @NotNull PsiType[] types) { + if (types.length == 0 && annotations.length == 0) { return refName != null ? refName : ""; } StringBuilder buffer = new StringBuilder(); - - if (annotations.length > 0) { - for (PsiAnnotation annotation : annotations) { - buffer.append(annotation.getText()).append(' '); - } - } - + appendAnnotations(buffer, annotations, false); buffer.append(refName); - - if (typeParameters.length > 0) { - buffer.append("<"); - for (int i = 0; i < typeParameters.length; i++) { - buffer.append(typeParameters[i].getPresentableText()); - if (i < typeParameters.length - 1) buffer.append(", "); - } - buffer.append(">"); - } - + appendTypeArgs(buffer, types, false, true); return buffer.toString(); } @@ -262,4 +250,43 @@ public abstract class PsiNameHelper { return subpackageName.equals(packageName) || subpackageName.startsWith(packageName) && subpackageName.charAt(packageName.length()) == '.'; } + + public static void appendTypeArgs(@NotNull StringBuilder sb, @NotNull PsiType[] types, boolean canonical, boolean annotated) { + if (types.length == 0) return; + + sb.append('<'); + for (int i = 0; i < types.length; i++) { + if (i > 0) { + sb.append(canonical ? "," : ", "); + } + + PsiType type = types[i]; + if (canonical) { + sb.append(type.getCanonicalText(annotated)); + } + else { + sb.append(type.getPresentableText()); + } + } + sb.append('>'); + } + + public static boolean appendAnnotations(@NotNull StringBuilder sb, @NotNull PsiAnnotation[] annotations, boolean canonical) { + return appendAnnotations(sb, Arrays.asList(annotations), canonical); + } + + public static boolean appendAnnotations(@NotNull StringBuilder sb, @NotNull List<PsiAnnotation> annotations, boolean canonical) { + for (PsiAnnotation annotation : annotations) { + sb.append('@'); + if (canonical) { + sb.append(annotation.getQualifiedName()); + sb.append(annotation.getParameterList().getText()); + } + else { + sb.append(assertNotNull(annotation.getNameReferenceElement()).getText()); + } + sb.append(' '); + } + return annotations.size() > 0; + } } diff --git a/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java b/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java index dd6b0d4d6ef9..cad6cfda7234 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java @@ -30,7 +30,7 @@ import java.util.Map; /** * Represents primitive types of Java language. */ -public class PsiPrimitiveType extends PsiType { +public class PsiPrimitiveType extends PsiType.Stub { private static final Map<String, PsiPrimitiveType> ourQNameToUnboxed = new THashMap<String, PsiPrimitiveType>(); private static final Map<PsiPrimitiveType, String> ourUnboxedToQName = new THashMap<PsiPrimitiveType, String>(); @@ -52,19 +52,29 @@ public class PsiPrimitiveType extends PsiType { @NotNull @Override public String getPresentableText() { - return getAnnotationsTextPrefix(false, false, true) + myName; + return getText(false, true); } @NotNull @Override - public String getCanonicalText() { - return myName; + public String getCanonicalText(boolean annotated) { + return getText(true, annotated); } @NotNull @Override public String getInternalCanonicalText() { - return getAnnotationsTextPrefix(true, false, true) + myName; + return getText(true, true); + } + + private String getText(boolean qualified, boolean annotated) { + PsiAnnotation[] annotations = getAnnotations(); + if (!annotated || annotations.length == 0) return myName; + + StringBuilder sb = new StringBuilder(); + PsiNameHelper.appendAnnotations(sb, annotations, qualified); + sb.append(myName); + return sb.toString(); } /** diff --git a/java/java-psi-api/src/com/intellij/psi/PsiType.java b/java/java-psi-api/src/com/intellij/psi/PsiType.java index cfbf026067bc..1dd67fb31a7f 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiType.java @@ -84,6 +84,15 @@ public abstract class PsiType implements PsiAnnotationOwner { */ @NonNls @NotNull + public String getCanonicalText(boolean annotated) { + return getCanonicalText(); + } + + /** + * Same as {@code getCanonicalText(false)}. + */ + @NonNls + @NotNull public abstract String getCanonicalText(); /** @@ -284,24 +293,15 @@ public abstract class PsiType implements PsiAnnotationOwner { return getAnnotations(); } - @NotNull + /** @deprecated use {@link PsiNameHelper#appendAnnotations(StringBuilder, PsiAnnotation[], boolean)} (to remove in IDEA 14) */ + @SuppressWarnings("UnusedDeclaration") protected String getAnnotationsTextPrefix(boolean qualified, boolean leadingSpace, boolean trailingSpace) { PsiAnnotation[] annotations = getAnnotations(); if (annotations.length == 0) return ""; StringBuilder sb = new StringBuilder(); if (leadingSpace) sb.append(' '); - for (int i = 0; i < annotations.length; i++) { - if (i > 0) sb.append(' '); - PsiAnnotation annotation = annotations[i]; - if (qualified) { - sb.append('@').append(annotation.getQualifiedName()).append(annotation.getParameterList().getText()); - } - else { - sb.append(annotation.getText()); - } - } - if (trailingSpace) sb.append(' '); + if (PsiNameHelper.appendAnnotations(sb, annotations, qualified) &&!trailingSpace) sb.setLength(sb.length() - 1); return sb.toString(); } @@ -310,4 +310,23 @@ public abstract class PsiType implements PsiAnnotationOwner { //noinspection HardCodedStringLiteral return "PsiType:" + getPresentableText(); } + + /** + * Temporary class to facilitate transition to {@link #getCanonicalText(boolean)}. + */ + protected static abstract class Stub extends PsiType { + protected Stub(@NotNull PsiAnnotation[] annotations) { + super(annotations); + } + + @NotNull + @Override + public final String getCanonicalText() { + return getCanonicalText(false); + } + + @NotNull + @Override + public abstract String getCanonicalText(boolean annotated); + } } diff --git a/java/java-psi-api/src/com/intellij/psi/PsiWildcardType.java b/java/java-psi-api/src/com/intellij/psi/PsiWildcardType.java index a3dd77aae361..d6518104b014 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiWildcardType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiWildcardType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ import org.jetbrains.annotations.Nullable; * * @author dsl */ -public class PsiWildcardType extends PsiType { +public class PsiWildcardType extends PsiType.Stub { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.PsiWildcardType"); private static final Key<PsiWildcardType> UNBOUNDED_WILDCARD = new Key<PsiWildcardType>("UNBOUNDED_WILDCARD"); @@ -83,21 +83,37 @@ public class PsiWildcardType extends PsiType { @NotNull @Override public String getPresentableText() { - return getAnnotationsTextPrefix(false, false, true) + - (myBound == null ? "?" : (myIsExtending ? EXTENDS_PREFIX : SUPER_PREFIX) + myBound.getPresentableText()); + return getText(false, true, myBound == null ? null : myBound.getPresentableText()); } @Override @NotNull - public String getCanonicalText() { - return myBound == null ? "?" : (myIsExtending ? EXTENDS_PREFIX : SUPER_PREFIX) + myBound.getCanonicalText(); + public String getCanonicalText(boolean annotated) { + return getText(true, annotated, myBound == null ? null : myBound.getCanonicalText(annotated)); } @NotNull @Override public String getInternalCanonicalText() { - return getAnnotationsTextPrefix(true, false, true) + - (myBound == null ? "?" : (myIsExtending ? EXTENDS_PREFIX : SUPER_PREFIX) + myBound.getInternalCanonicalText()); + return getText(true, true, myBound == null ? null : myBound.getInternalCanonicalText()); + } + + private String getText(boolean qualified, boolean annotated, @Nullable String suffix) { + PsiAnnotation[] annotations = getAnnotations(); + if ((!annotated || annotations.length == 0) && suffix == null) return "?"; + + StringBuilder sb = new StringBuilder(); + if (annotated) { + PsiNameHelper.appendAnnotations(sb, annotations, qualified); + } + if (suffix == null) { + sb.append('?'); + } + else { + sb.append(myIsExtending ? EXTENDS_PREFIX : SUPER_PREFIX); + sb.append(suffix); + } + return sb.toString(); } @Override diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java index 0de45be17786..77fd0081d161 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java @@ -493,6 +493,13 @@ public class PsiImplUtil { return PsiUtil.captureToplevelWildcards(type, expression); } + final PsiElement parent = toplevel.getParent(); + if (parent instanceof PsiExpressionList && + PsiUtil.isLanguageLevel8OrHigher(parent) && + parent.getParent() instanceof PsiCallExpression) { + return PsiUtil.captureToplevelWildcards(type, expression); + } + final PsiType normalized = doNormalizeWildcardByPosition(type, expression, toplevel); LOG.assertTrue(normalized.isValid(), type); if (normalized instanceof PsiClassType && !PsiUtil.isAccessedForWriting(toplevel)) { 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 36a725aa3135..369ce919f5a1 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 @@ -15,15 +15,18 @@ */ package com.intellij.psi.impl.compiled; +import com.intellij.diagnostic.PluginException; import com.intellij.ide.caches.FileContent; import com.intellij.ide.highlighter.JavaClassFileType; import com.intellij.ide.highlighter.JavaFileType; +import com.intellij.ide.plugins.PluginManagerCore; import com.intellij.lang.ASTNode; import com.intellij.lang.FileASTNode; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.progress.NonCancelableSection; import com.intellij.openapi.progress.ProgressIndicatorProvider; @@ -35,6 +38,7 @@ import com.intellij.openapi.util.ModificationTracker; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; +import com.intellij.psi.compiled.ClassFileDecompilers; import com.intellij.psi.impl.JavaPsiImplementationHelper; import com.intellij.psi.impl.PsiFileEx; import com.intellij.psi.impl.java.stubs.PsiClassStub; @@ -324,7 +328,7 @@ public class ClsFileImpl extends ClsRepositoryPsiElement<PsiClassHolderFileStub> setMirror(mirrorTreeElement); } catch (InvalidMirrorException e) { - LOG.error(file.getPath(), e); + LOG.error(file.getPath(), wrapException(e, file)); } finally { section.done(); @@ -337,6 +341,18 @@ public class ClsFileImpl extends ClsRepositoryPsiElement<PsiClassHolderFileStub> return mirrorTreeElement.getPsi(); } + private static Exception wrapException(InvalidMirrorException e, VirtualFile file) { + ClassFileDecompilers.Decompiler decompiler = ClassFileDecompilers.find(file); + if (decompiler instanceof ClassFileDecompilers.Light) { + PluginId pluginId = PluginManagerCore.getPluginByClassName(decompiler.getClass().getName()); + if (pluginId != null) { + return new PluginException(e, pluginId); + } + } + + return e; + } + @Override public PsiFile getDecompiledPsiFile() { return (PsiFile)getMirror(); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java index 599f756adbc1..16d971238684 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java @@ -17,8 +17,7 @@ package com.intellij.psi.impl.compiled; import com.intellij.openapi.util.AtomicNotNullLazyValue; import com.intellij.openapi.util.NotNullLazyValue; -import com.intellij.openapi.util.NullableLazyValue; -import com.intellij.openapi.util.VolatileNullableLazyValue; +import com.intellij.openapi.util.Ref; import com.intellij.psi.*; import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.impl.PsiJavaParserFacadeImpl; @@ -28,7 +27,6 @@ import com.intellij.psi.impl.source.tree.JavaElementType; import com.intellij.psi.impl.source.tree.TreeElement; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; public class ClsTypeElementImpl extends ClsElementImpl implements PsiTypeElement { @NonNls static final char VARIANCE_NONE = '\0'; @@ -41,18 +39,18 @@ public class ClsTypeElementImpl extends ClsElementImpl implements PsiTypeElement private final PsiElement myParent; private final String myTypeText; private final char myVariance; - private final NullableLazyValue<ClsElementImpl> myChild; + private final NotNullLazyValue<Ref<ClsElementImpl>> myChild; private final NotNullLazyValue<PsiType> myCachedType; public ClsTypeElementImpl(@NotNull PsiElement parent, @NotNull String typeText, char variance) { myParent = parent; myTypeText = TypeInfo.internFrequentType(typeText); myVariance = variance; - myChild = new VolatileNullableLazyValue<ClsElementImpl>() { - @Nullable + myChild = new AtomicNotNullLazyValue<Ref<ClsElementImpl>>() { + @NotNull @Override - protected ClsElementImpl compute() { - return calculateChild(); + protected Ref<ClsElementImpl> compute() { + return Ref.create(calculateChild()); } }; myCachedType = new AtomicNotNullLazyValue<PsiType>() { @@ -67,7 +65,7 @@ public class ClsTypeElementImpl extends ClsElementImpl implements PsiTypeElement @Override @NotNull public PsiElement[] getChildren() { - ClsElementImpl child = myChild.getValue(); + ClsElementImpl child = myChild.getValue().get(); return child != null ? new PsiElement[]{child} : PsiElement.EMPTY_ARRAY; } @@ -111,7 +109,7 @@ public class ClsTypeElementImpl extends ClsElementImpl implements PsiTypeElement public void setMirror(@NotNull TreeElement element) throws InvalidMirrorException { setMirrorCheckingType(element, JavaElementType.TYPE); - ClsElementImpl child = myChild.getValue(); + ClsElementImpl child = myChild.getValue().get(); if (child != null) { child.setMirror(element.getFirstChildNode()); } @@ -157,7 +155,7 @@ public class ClsTypeElementImpl extends ClsElementImpl implements PsiTypeElement PsiType result = PsiJavaParserFacadeImpl.getPrimitiveType(myTypeText); if (result != null) return result; - ClsElementImpl childElement = myChild.getValue(); + ClsElementImpl childElement = myChild.getValue().get(); if (childElement instanceof ClsTypeElementImpl) { if (isArray()) { switch (myVariance) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java index a43c02d8a7a4..f304fe250bae 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,16 +30,16 @@ import java.util.List; /** * @author max */ -public class PsiClassReferenceType extends PsiClassType { +public class PsiClassReferenceType extends PsiClassType.Stub { @NotNull private final PsiJavaCodeReferenceElement myReference; - public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel langLevel) { - this(reference, langLevel, collectAnnotations(reference)); + public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel level) { + this(reference, level, collectAnnotations(reference)); } - public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel langLevel, @NotNull PsiAnnotation[] annotations) { - super(langLevel, annotations); + public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel level, @NotNull PsiAnnotation[] annotations) { + super(level, annotations); myReference = reference; } @@ -89,7 +89,7 @@ public class PsiClassReferenceType extends PsiClassType { return resolveGenerics().getElement(); } - private static class DelegatingClassResolveResult implements ClassResolveResult { + private static class DelegatingClassResolveResult implements PsiClassType.ClassResolveResult { private final JavaResolveResult myDelegate; private DelegatingClassResolveResult(@NotNull JavaResolveResult delegate) { @@ -182,19 +182,37 @@ public class PsiClassReferenceType extends PsiClassType { @NotNull @Override public String getPresentableText() { - return getAnnotationsTextPrefix(false, false, true) + PsiNameHelper.getPresentableText(myReference); + String presentableText = PsiNameHelper.getPresentableText(myReference); + PsiAnnotation[] annotations = getAnnotations(); + if (annotations.length == 0) return presentableText; + + StringBuilder sb = new StringBuilder(); + PsiNameHelper.appendAnnotations(sb, annotations, false); + sb.append(presentableText); + return sb.toString(); } @NotNull @Override - public String getCanonicalText() { - return myReference.getCanonicalText(); + public String getCanonicalText(boolean annotated) { + return getText(annotated); } @NotNull @Override public String getInternalCanonicalText() { - return getAnnotationsTextPrefix(true, false, true) + getCanonicalText(); + return getText(true); + } + + private String getText(boolean annotated) { + if (myReference instanceof PsiJavaCodeReferenceElementImpl) { + PsiAnnotation[] annotations = getAnnotations(); + if (!annotated || annotations.length == 0) annotations = null; + return ((PsiJavaCodeReferenceElementImpl)myReference).getCanonicalText(annotated, annotations); + } + else { + return myReference.getCanonicalText(); + } } @NotNull diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java index 9456c29f6ceb..77a45011144d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ */ package com.intellij.psi.impl.source; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; @@ -30,11 +31,12 @@ import java.util.List; /** * @author dsl */ -public class PsiImmediateClassType extends PsiClassType { +public class PsiImmediateClassType extends PsiClassType.Stub { private final PsiClass myClass; private final PsiSubstitutor mySubstitutor; private final PsiManager myManager; private String myCanonicalText; + private String myCanonicalTextAnnotated; private String myPresentableText; private String myInternalCanonicalText; @@ -80,15 +82,15 @@ public class PsiImmediateClassType extends PsiClassType { this(aClass, substitutor, null, PsiAnnotation.EMPTY_ARRAY); } - public PsiImmediateClassType(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor, @Nullable LanguageLevel languageLevel) { - this(aClass, substitutor, languageLevel, PsiAnnotation.EMPTY_ARRAY); + public PsiImmediateClassType(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor, @Nullable LanguageLevel level) { + this(aClass, substitutor, level, PsiAnnotation.EMPTY_ARRAY); } public PsiImmediateClassType(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor, - @Nullable LanguageLevel languageLevel, - @NotNull PsiAnnotation[] annotations) { - super(languageLevel, annotations); + @Nullable LanguageLevel level, + @NotNull PsiAnnotation... annotations) { + super(level, annotations); myClass = aClass; myManager = aClass.getManager(); mySubstitutor = substitutor; @@ -138,112 +140,119 @@ public class PsiImmediateClassType extends PsiClassType { @Override public String getPresentableText() { if (myPresentableText == null) { - StringBuilder buffer = new StringBuilder(); - buildText(myClass, mySubstitutor, buffer, false, false); - myPresentableText = buffer.toString(); + myPresentableText = getText(TextType.PRESENTABLE, true); } return myPresentableText; } @NotNull @Override - public String getCanonicalText() { - if (myCanonicalText == null) { - assert mySubstitutor.isValid(); - StringBuilder buffer = new StringBuilder(); - buildText(myClass, mySubstitutor, buffer, true, false); - myCanonicalText = buffer.toString(); + public String getCanonicalText(boolean annotated) { + String cached = annotated ? myCanonicalTextAnnotated : myCanonicalText; + if (cached == null) { + cached = getText(TextType.CANONICAL, annotated); + if (annotated) myCanonicalTextAnnotated = cached; + else myCanonicalText = cached; } - return myCanonicalText; + return cached; } @NotNull @Override public String getInternalCanonicalText() { if (myInternalCanonicalText == null) { - StringBuilder buffer = new StringBuilder(); - buildText(myClass, mySubstitutor, buffer, true, true); - myInternalCanonicalText = buffer.toString(); + myInternalCanonicalText = getText(TextType.INT_CANONICAL, true); } return myInternalCanonicalText; } + private enum TextType { PRESENTABLE, CANONICAL, INT_CANONICAL } + + private String getText(@NotNull TextType textType, boolean annotated) { + assert mySubstitutor.isValid(); + StringBuilder buffer = new StringBuilder(); + buildText(myClass, mySubstitutor, buffer, textType, annotated); + return buffer.toString(); + } + private void buildText(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor, @NotNull StringBuilder buffer, - boolean canonical, - boolean internal) { + @NotNull TextType textType, + boolean annotated) { if (aClass instanceof PsiAnonymousClass) { - ClassResolveResult baseResolveResult = ((PsiAnonymousClass) aClass).getBaseClassType().resolveGenerics(); + ClassResolveResult baseResolveResult = ((PsiAnonymousClass)aClass).getBaseClassType().resolveGenerics(); PsiClass baseClass = baseResolveResult.getElement(); - PsiSubstitutor baseSub = baseResolveResult.getSubstitutor(); if (baseClass != null) { - buildText(baseClass, baseSub, buffer, canonical, internal); + buildText(baseClass, baseResolveResult.getSubstitutor(), buffer, textType, false); } return; } - if (canonical == internal) { - buffer.append(getAnnotationsTextPrefix(internal, false, true)); - } + boolean qualified = textType != TextType.PRESENTABLE; PsiClass enclosingClass = null; if (!aClass.hasModifierProperty(PsiModifier.STATIC)) { - final PsiElement parent = aClass.getParent(); + PsiElement parent = aClass.getParent(); if (parent instanceof PsiClass && !(parent instanceof PsiAnonymousClass)) { enclosingClass = (PsiClass)parent; } } if (enclosingClass != null) { - buildText(enclosingClass, substitutor, buffer, canonical, false); + buildText(enclosingClass, substitutor, buffer, textType, false); buffer.append('.'); - buffer.append(aClass.getName()); } - else { - final String name; - if (!canonical) { - name = aClass.getName(); - } - else { - final String qualifiedName = aClass.getQualifiedName(); - if (qualifiedName == null) { - name = aClass.getName(); - } - else { - name = qualifiedName; + else if (qualified) { + String fqn = aClass.getQualifiedName(); + if (fqn != null) { + String prefix = StringUtil.getPackageName(fqn); + if (!StringUtil.isEmpty(prefix)) { + buffer.append(prefix); + buffer.append('.'); } } - buffer.append(name); } + if (annotated) { + PsiNameHelper.appendAnnotations(buffer, getAnnotations(), qualified); + } + + buffer.append(aClass.getName()); + PsiTypeParameter[] typeParameters = aClass.getTypeParameters(); if (typeParameters.length > 0) { - StringBuilder pineBuffer = new StringBuilder(); - pineBuffer.append('<'); + int pos = buffer.length(); + buffer.append('<'); + for (int i = 0; i < typeParameters.length; i++) { PsiTypeParameter typeParameter = typeParameters[i]; PsiUtilCore.ensureValid(typeParameter); - if (i > 0) pineBuffer.append(','); - final PsiType substitutionResult = substitutor.substitute(typeParameter); + + if (i > 0) { + buffer.append(','); + if (textType == TextType.PRESENTABLE) buffer.append(' '); + } + + PsiType substitutionResult = substitutor.substitute(typeParameter); if (substitutionResult == null) { - pineBuffer = null; + buffer.setLength(pos); + pos = -1; break; } PsiUtil.ensureValidType(substitutionResult); - if (canonical) { - if (internal) { - pineBuffer.append(substitutionResult.getInternalCanonicalText()); - } - else { - pineBuffer.append(substitutionResult.getCanonicalText()); - } + + if (textType == TextType.PRESENTABLE) { + buffer.append(substitutionResult.getPresentableText()); + } + else if (textType == TextType.CANONICAL) { + buffer.append(substitutionResult.getCanonicalText(annotated)); } else { - pineBuffer.append(substitutionResult.getPresentableText()); + buffer.append(substitutionResult.getInternalCanonicalText()); } } - if (pineBuffer != null) { - buffer.append(pineBuffer); + + if (pos >= 0) { buffer.append('>'); } } @@ -265,7 +274,6 @@ public class PsiImmediateClassType extends PsiClassType { return false; } return equals(patternType); - } @Override @@ -277,14 +285,12 @@ public class PsiImmediateClassType extends PsiClassType { @Override @NotNull public LanguageLevel getLanguageLevel() { - if (myLanguageLevel != null) return myLanguageLevel; - return PsiUtil.getLanguageLevel(myClass); + return myLanguageLevel != null ? myLanguageLevel : PsiUtil.getLanguageLevel(myClass); } @NotNull @Override - public PsiClassType setLanguageLevel(@NotNull final LanguageLevel languageLevel) { - if (languageLevel.equals(myLanguageLevel)) return this; - return new PsiImmediateClassType(myClass, mySubstitutor, languageLevel,getAnnotations()); + public PsiClassType setLanguageLevel(@NotNull LanguageLevel level) { + return level.equals(myLanguageLevel) ? this : new PsiImmediateClassType(myClass, mySubstitutor, level, getAnnotations()); } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java index 396b750c8c2a..5ee1243b09ce 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,6 +49,7 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; import java.util.List; public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement implements PsiJavaCodeReferenceElement, SourceJavaCodeReference { @@ -255,36 +256,47 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme @Override @NotNull public String getCanonicalText() { + return getCanonicalText(false, null); + } + + @NotNull + public String getCanonicalText(boolean annotated, @Nullable PsiAnnotation[] annotations) { switch (getKind()) { case CLASS_NAME_KIND: case CLASS_OR_PACKAGE_NAME_KIND: case CLASS_IN_QUALIFIED_NEW_KIND: final PsiElement target = resolve(); if (target instanceof PsiClass) { - final PsiClass aClass = (PsiClass)target; - String name = aClass.getQualifiedName(); - if (name == null) { - name = aClass.getName(); //? + PsiClass aClass = (PsiClass)target; + StringBuilder buffer = new StringBuilder(); + + PsiElement qualifier = getQualifier(); + String prefix = null; + if (qualifier instanceof PsiJavaCodeReferenceElementImpl) { + prefix = ((PsiJavaCodeReferenceElementImpl)qualifier).getCanonicalText(annotated, null); } - final PsiType[] types = getTypeParameters(); - if (types.length == 0) { - final PsiElement qualifier = getQualifier(); - if (qualifier instanceof PsiJavaCodeReferenceElement) { - return StringUtil.getQualifiedName(((PsiJavaCodeReferenceElement)qualifier).getCanonicalText(), aClass.getName()); + else { + String fqn = aClass.getQualifiedName(); + if (fqn != null) { + prefix = StringUtil.getPackageName(fqn); } - return name; } - final StringBuilder buf = new StringBuilder(); - buf.append(name); - buf.append('<'); - for (int i = 0; i < types.length; i++) { - if (i > 0) buf.append(','); - buf.append(types[i].getCanonicalText()); + if (!StringUtil.isEmpty(prefix)) { + buffer.append(prefix); + buffer.append('.'); } - buf.append('>'); - return buf.toString(); + if (annotated) { + List<PsiAnnotation> list = annotations != null ? Arrays.asList(annotations) : getAnnotations(); + PsiNameHelper.appendAnnotations(buffer, list, true); + } + + buffer.append(aClass.getName()); + + PsiNameHelper.appendTypeArgs(buffer, getTypeParameters(), true, annotated); + + return buffer.toString(); } else if (target instanceof PsiPackage) { return ((PsiPackage)target).getQualifiedName(); @@ -293,6 +305,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme LOG.assertTrue(target == null, target); return getNormalizedText(); } + case PACKAGE_NAME_KIND: case CLASS_FQ_NAME_KIND: case CLASS_FQ_OR_PACKAGE_NAME_KIND: @@ -327,7 +340,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme if (incompleteCode && result.length == 0 && kind != CLASS_FQ_NAME_KIND && kind != CLASS_FQ_OR_PACKAGE_NAME_KIND) { VariableResolverProcessor processor = new VariableResolverProcessor(referenceElement, containingFile); - PsiScopesUtil.resolveAndWalk(processor, referenceElement, null, incompleteCode); + PsiScopesUtil.resolveAndWalk(processor, referenceElement, null, true); result = processor.getResult(); if (result.length == 0 && kind == CLASS_NAME_KIND) { result = referenceElement.resolve(PACKAGE_NAME_KIND, containingFile); @@ -457,16 +470,16 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme case CLASS_FQ_OR_PACKAGE_NAME_KIND: case CLASS_OR_PACKAGE_NAME_KIND: { int classKind = kind == CLASS_OR_PACKAGE_NAME_KIND ? CLASS_NAME_KIND : CLASS_FQ_NAME_KIND; - JavaResolveResult[] result = resolve(classKind,containingFile); + JavaResolveResult[] result = resolve(classKind, containingFile); if (result.length == 1 && !result[0].isAccessible()) { - JavaResolveResult[] packageResult = resolve(PACKAGE_NAME_KIND,containingFile); + JavaResolveResult[] packageResult = resolve(PACKAGE_NAME_KIND, containingFile); if (packageResult.length != 0) { result = packageResult; } } else if (result.length == 0) { - result = resolve(PACKAGE_NAME_KIND,containingFile); + result = resolve(PACKAGE_NAME_KIND, containingFile); } return result; @@ -607,7 +620,12 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme for (PsiAnnotation annotation : annotations) { if (annotation.getParent() != newParent) { - newParent.addAfter(annotation, anchor); + if (anchor != null) { + newParent.addAfter(annotation, anchor); + } + else { + newParent.add(annotation); + } annotation.delete(); } } @@ -935,7 +953,6 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme final PsiReferenceParameterList parameterList = getParameterList(); if (parameterList == null) return PsiType.EMPTY_ARRAY; return parameterList.getTypeArguments(); - } @Override diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java index 5b76439ef406..20db589bef5c 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java @@ -225,15 +225,21 @@ public class JavaResolveUtil { return true; } - public static void substituteResults(@NotNull PsiJavaCodeReferenceElement ref, @NotNull JavaResolveResult[] result) { + public static void substituteResults(final @NotNull PsiJavaCodeReferenceElement ref, @NotNull JavaResolveResult[] result) { if (result.length > 0 && result[0].getElement() instanceof PsiClass) { - PsiType[] parameters = ref.getTypeParameters(); for (int i = 0; i < result.length; i++) { - CandidateInfo resolveResult = (CandidateInfo)result[i]; - PsiElement resultElement = resolveResult.getElement(); + final CandidateInfo resolveResult = (CandidateInfo)result[i]; + final PsiElement resultElement = resolveResult.getElement(); if (resultElement instanceof PsiClass && ((PsiClass)resultElement).hasTypeParameters()) { - PsiSubstitutor substitutor = resolveResult.getSubstitutor().putAll((PsiClass)resultElement, parameters); - result[i] = new CandidateInfo(resolveResult, substitutor); + PsiSubstitutor substitutor = resolveResult.getSubstitutor(); + result[i] = new CandidateInfo(resolveResult, substitutor) { + @NotNull + @Override + public PsiSubstitutor getSubstitutor() { + final PsiType[] parameters = ref.getTypeParameters(); + return super.getSubstitutor().putAll((PsiClass)resultElement, parameters); + } + }; } } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java index a52ea73a18d5..b4b188c772cc 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java @@ -18,7 +18,6 @@ package com.intellij.psi.impl.source.resolve.graphInference; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.graphInference.constraints.TypeEqualityConstraint; -import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.Nullable; @@ -102,7 +101,7 @@ public class FunctionalInterfaceParameterizationUtil { return null; } - final PsiSubstitutor substitutor = session.resolveDependencies(session.getInferenceVariables()); + final PsiSubstitutor substitutor = session.retrieveNonPrimitiveEqualsBounds(session.getInferenceVariables()); final PsiType[] newTypeParameters = new PsiType[parameters.length]; for (int i = 0; i < typeParameters.length; i++) { PsiTypeParameter typeParameter = typeParameters[i]; @@ -119,14 +118,10 @@ public class FunctionalInterfaceParameterizationUtil { return null; } - if (!TypeConversionUtil.containsWildcards(parameterization)) { + if (!TypeConversionUtil.containsWildcards(parameterization) && psiClassType.isAssignableFrom(parameterization)) { return parameterization; } - if (!psiClassType.isAssignableFrom(parameterization)) { - return null; - } - return getNonWildcardParameterization((PsiClassType)psiClassType); } return null; @@ -169,27 +164,32 @@ public class FunctionalInterfaceParameterizationUtil { for (int i = 0; i < parameters.length; i++) { PsiType paramType = parameters[i]; if (paramType instanceof PsiWildcardType) { - final PsiClassType[] extendsListTypes = typeParameters[i].getExtendsListTypes(); - final PsiClassType Bi = extendsListTypes.length > 0 ? extendsListTypes[0] - : PsiType.getJavaLangObject(psiClass.getManager(), - GlobalSearchScope.allScope(psiClass.getProject())); - if (PsiPolyExpressionUtil.mentionsTypeParameters(Bi, typeParametersSet)) { - return null; + final PsiType bound = GenericsUtil.eliminateWildcards(((PsiWildcardType)paramType).getBound(), false); + if (((PsiWildcardType)paramType).isSuper()) { + newParameters[i] = bound; } - - final PsiType bound = ((PsiWildcardType)paramType).getBound(); - if (bound == null) { - newParameters[i] = Bi; - } else if (((PsiWildcardType)paramType).isExtends()){ - newParameters[i] = GenericsUtil.getGreatestLowerBound(Bi, GenericsUtil.eliminateWildcards(bound, false)); - } else { - newParameters[i] = GenericsUtil.eliminateWildcards(bound, false); + else { + newParameters[i] = bound != null ? bound : PsiType.getJavaLangObject(psiClass.getManager(), psiClassType.getResolveScope()); + for (PsiClassType paramBound : typeParameters[i].getExtendsListTypes()) { + if (!PsiPolyExpressionUtil.mentionsTypeParameters(paramBound, typeParametersSet)) { + newParameters[i] = GenericsUtil.getGreatestLowerBound(paramBound, newParameters[i]); + } + } } } else { newParameters[i] = paramType; } } - return JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass, newParameters); + + if (!isWellFormed(psiClass, typeParameters, newParameters)) { + return null; + } + + final PsiClassType parameterization = JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass, newParameters); + if (!psiClassType.isAssignableFrom(parameterization)) { + return null; + } + return parameterization; } return null; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java index cc666815c2d2..f30c7ae6382c 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java @@ -110,18 +110,6 @@ public class InferenceIncorporationPhase { } } } - - //todo no such a rule in spec?! - for (PsiType lowerBound : lowerBounds) { - if (mySession.isProperType(lowerBound)) { - final PsiSubstitutor substitutor = PsiSubstitutor.EMPTY.put(inferenceVariable.getParameter(), lowerBound); - for (PsiType upperBound : upperBounds) { - if (!mySession.isProperType(upperBound)) { - addConstraint(new StrictSubtypingConstraint(substitutor.substitute(upperBound), lowerBound)); - } - } - } - } } for (Pair<PsiTypeParameter[], PsiClassType> capture : myCaptures) { @@ -389,21 +377,4 @@ public class InferenceIncorporationPhase { } } } - - public PsiSubstitutor checkIncorporated(PsiSubstitutor substitutor, Collection<InferenceVariable> variables) { - for (InferenceVariable variable : variables) { //todo equals bounds? - for (PsiType lowerBound : variable.getBounds(InferenceBound.LOWER)) { - lowerBound = substitutor.substitute(lowerBound); - if (mySession.isProperType(lowerBound)) { - for (PsiType upperBound : variable.getBounds(InferenceBound.UPPER)) { - upperBound = substitutor.substitute(upperBound); - if (mySession.isProperType(upperBound) && !TypeConversionUtil.isAssignable(upperBound, lowerBound)) { - return null; - } - } - } - } - } - return substitutor; - } } 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 abde4616fe77..53911011bc17 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 @@ -20,15 +20,8 @@ import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.psi.*; -import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.impl.source.resolve.graphInference.constraints.*; import com.intellij.psi.infos.MethodCandidateInfo; -import com.intellij.psi.scope.MethodProcessorSetupFailedException; -import com.intellij.psi.scope.PsiConflictResolver; -import com.intellij.psi.scope.conflictResolvers.JavaMethodsConflictResolver; -import com.intellij.psi.scope.processor.MethodCandidatesProcessor; -import com.intellij.psi.scope.processor.MethodResolverProcessor; -import com.intellij.psi.scope.util.PsiScopesUtil; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTypesUtil; @@ -174,7 +167,8 @@ public class InferenceSession { return true; } - private static PsiType getParameterType(PsiParameter[] parameters, PsiExpression[] args, int i, PsiSubstitutor substitutor) { + private static PsiType getParameterType(PsiParameter[] parameters, PsiExpression[] args, int i, @Nullable PsiSubstitutor substitutor) { + if (substitutor == null) return null; PsiType parameterType = substitutor.substitute(parameters[i < parameters.length ? i : parameters.length - 1].getType()); if (parameterType instanceof PsiEllipsisType) { final PsiExpression arg = args[i]; @@ -213,7 +207,7 @@ public class InferenceSession { PsiMethod parentMethod) { if (!repeatInferencePhases(true)) { //inferred result would be checked as candidate won't be applicable - return resolveSubset(myInferenceVariables.values(), mySiteSubstitutor, false); + return resolveSubset(myInferenceVariables.values(), mySiteSubstitutor); } if (parentMethod != null) { @@ -299,17 +293,17 @@ public class InferenceSession { } } } else { - return resolveSubset(myInferenceVariables.values(), mySiteSubstitutor, false); + return resolveSubset(myInferenceVariables.values(), mySiteSubstitutor); } return prepareSubstitution(); } - public PsiSubstitutor resolveDependencies(Collection<InferenceVariable> variables) { + public PsiSubstitutor retrieveNonPrimitiveEqualsBounds(Collection<InferenceVariable> variables) { PsiSubstitutor substitutor = mySiteSubstitutor; for (InferenceVariable variable : variables) { final PsiType equalsBound = getEqualsBound(variable, substitutor); - if (equalsBound != PsiType.NULL) { + if (!(equalsBound instanceof PsiPrimitiveType)) { substitutor = substitutor.put(variable.getParameter(), equalsBound); } } @@ -340,9 +334,13 @@ public class InferenceSession { return false; } - public void initBounds(PsiTypeParameter... typeParameters) { + public boolean initBounds(PsiTypeParameter... typeParameters) { + boolean sameMethodCall = false; for (PsiTypeParameter parameter : typeParameters) { - if (myInferenceVariables.containsKey(parameter)) continue; + if (myInferenceVariables.containsKey(parameter)) { + sameMethodCall = true; + continue; + } InferenceVariable variable = new InferenceVariable(parameter); boolean added = false; final PsiClassType[] extendsListTypes = parameter.getExtendsListTypes(); @@ -359,29 +357,19 @@ public class InferenceSession { } myInferenceVariables.put(parameter, variable); } - } - - public void addCapturedVariable(PsiTypeParameter param) { - initBounds(param); + return sameMethodCall; } private void initReturnTypeConstraint(PsiMethod method, final PsiCallExpression context) { - if (PsiPolyExpressionUtil.isMethodCallPolyExpression(context, method) || - context instanceof PsiNewExpression && PsiDiamondType.ourDiamondGuard.currentStack().contains(context)) { + if (PsiPolyExpressionUtil.isMethodCallPolyExpression(context, method)) { PsiType returnType = method.getReturnType(); if (!PsiType.VOID.equals(returnType) && returnType != null) { - returnType = PsiImplUtil.normalizeWildcardTypeByPosition(returnType, context); PsiType targetType = PsiTypesUtil.getExpectedTypeByParent(context); if (targetType == null) { - targetType = PsiResolveHelper.ourGraphGuard.doPreventingRecursion(context, false, new Computable<PsiType>() { - @Override - public PsiType compute() { - return getTargetType(context); - } - }); + targetType = getTargetType(context); } if (targetType != null) { - registerConstraints(returnType, targetType); + registerConstraints(PsiUtil.isRawSubstitutor(method, mySiteSubstitutor) ? returnType : mySiteSubstitutor.substitute(returnType), targetType); } } } @@ -397,7 +385,7 @@ public class InferenceSession { public void registerConstraints(PsiType returnType, PsiType targetType) { final InferenceVariable inferenceVariable = shouldResolveAndInstantiate(returnType, targetType); if (inferenceVariable != null) { - final PsiSubstitutor substitutor = resolveSubset(Collections.singletonList(inferenceVariable), mySiteSubstitutor, true); + final PsiSubstitutor substitutor = resolveSubset(Collections.singletonList(inferenceVariable), mySiteSubstitutor); myConstraints.add(new TypeCompatibilityConstraint(targetType, PsiUtil.captureToplevelWildcards(substitutor.substitute(inferenceVariable.getParameter()), myContext))); } else { @@ -412,7 +400,7 @@ public class InferenceSession { PsiTypeParameter[] copy = new PsiTypeParameter[typeParameters.length]; for (int i = 0; i < typeParameters.length; i++) { PsiTypeParameter typeParameter = typeParameters[i]; - copy[i] = elementFactory.createTypeParameterFromText(typeParameter.getName(), null); + copy[i] = elementFactory.createTypeParameterFromText("rCopy" + typeParameter.getName(), null); initBounds(copy[i]); subst = subst.put(typeParameter, elementFactory.createType(copy[i])); } @@ -495,7 +483,7 @@ public class InferenceSession { return false; } - private PsiType getTargetType(final PsiExpression context) { + private static PsiType getTargetType(final PsiExpression context) { final PsiElement parent = PsiUtil.skipParenthesizedExprUp(context.getParent()); if (parent instanceof PsiExpressionList) { PsiElement gParent = parent.getParent(); @@ -505,28 +493,8 @@ public class InferenceSession { if (gParent instanceof PsiCallExpression) { final PsiExpressionList argumentList = ((PsiCallExpression)gParent).getArgumentList(); if (argumentList != null) { - final Pair<PsiMethod, PsiSubstitutor> pair = MethodCandidateInfo.getCurrentMethod(argumentList); - final PsiFile placeFile = context.getContainingFile(); - final JavaMethodsConflictResolver conflictResolver = new JavaMethodsConflictResolver(argumentList, PsiUtil.getLanguageLevel(placeFile)){ - @Override - protected PsiType[] getArgumentTypes() { - return InferenceSession.getArgumentTypes(argumentList, context); - } - }; - final MethodCandidatesProcessor processor = new MethodResolverProcessor((PsiCallExpression)gParent, placeFile, new PsiConflictResolver[]{conflictResolver}) { - @Override - protected PsiType[] getExpressionTypes(PsiExpressionList argumentList) { - return getArgumentTypes(argumentList, context); - } - }; - try { - PsiScopesUtil.setupAndRunProcessor(processor, (PsiCallExpression)gParent, false); - } - catch (MethodProcessorSetupFailedException e) { - return null; - } - final JavaResolveResult[] results = processor.getResult(); - return results.length == 1 ? getTypeByMethod(context, argumentList, pair, results[0], results[0].getElement()) : null; + final JavaResolveResult result = ((PsiCallExpression)gParent).resolveMethodGenerics(); + return getTypeByMethod(context, argumentList, result, result.getElement()); } } } else if (parent instanceof PsiConditionalExpression) { @@ -546,30 +514,9 @@ public class InferenceSession { return null; } - private static PsiType[] getArgumentTypes(PsiExpressionList argumentList, PsiExpression context) { - if (argumentList != null) { - final PsiExpression[] expressions = argumentList.getExpressions(); - final int idx = LambdaUtil.getLambdaIdx(argumentList, context); - final PsiType[] types = PsiType.createArray(expressions.length); - for (int i = 0; i < expressions.length; i++) { - if (i != idx) { - types[i] = expressions[i].getType(); - } - else { - types[i] = PsiType.NULL; - } - } - return types; - } - else { - return null; - } - } - - private PsiType getTypeByMethod(PsiExpression context, - PsiExpressionList argumentList, - Pair<PsiMethod, PsiSubstitutor> pair, - JavaResolveResult result, PsiElement parentMethod) { + private static PsiType getTypeByMethod(PsiExpression context, + PsiExpressionList argumentList, + final JavaResolveResult result, PsiElement parentMethod) { if (parentMethod instanceof PsiMethod) { final PsiParameter[] parameters = ((PsiMethod)parentMethod).getParameterList().getParameters(); if (parameters.length == 0) return null; @@ -581,23 +528,13 @@ public class InferenceSession { } final int i = ArrayUtilRt.find(args, arg); if (i < 0) return null; - final PsiCallExpression callExpression = PsiTreeUtil.getParentOfType(argumentList, PsiCallExpression.class); - if (callExpression != null && callExpression.getTypeArguments().length > 0) { - return getParameterType(parameters, args, i, ((MethodCandidateInfo)result).typeArgumentsSubstitutor()); - } - final PsiType parameterType = getParameterType(parameters, args, i, pair != null ? pair.second : PsiSubstitutor.EMPTY); - args[i] = null; - final PsiTypeParameter[] typeParameters = ((PsiMethod)parentMethod).getTypeParameters(); - final InferenceSession session = new InferenceSession(typeParameters, ((MethodCandidateInfo)result).getSiteSubstitutor(), myManager, argumentList); - session.initExpressionConstraints(parameters, args, argumentList, (PsiMethod)parentMethod); - if (session.tryToInfer(parameters, args, callExpression, (PsiMethod)parentMethod) != null) { - return null; - } - final Collection<PsiTypeParameter> params = session.getTypeParams(); - initBounds(params.toArray(new PsiTypeParameter[params.size()])); - liftBounds(session.getInferenceVariables()); - final PsiSubstitutor substitutor = ((MethodCandidateInfo)result).getSiteSubstitutor(); - return substitutor.substitute(parameterType); + return getParameterType(parameters, args, i, PsiResolveHelper.ourGraphGuard.doPreventingRecursion(argumentList.getParent(), false, + new Computable<PsiSubstitutor>() { + @Override + public PsiSubstitutor compute() { + return result.getSubstitutor(); + } + })); } return null; } @@ -720,7 +657,7 @@ public class InferenceSession { while (!allVars.isEmpty()) { final List<InferenceVariable> vars = InferenceVariablesOrder.resolveOrder(allVars, this); if (!myIncorporationPhase.hasCaptureConstraints(vars)) { - final PsiSubstitutor firstSubstitutor = resolveSubset(vars, substitutor, true); + final PsiSubstitutor firstSubstitutor = resolveSubset(vars, substitutor); if (firstSubstitutor != null) { substitutor = firstSubstitutor; allVars.removeAll(vars); @@ -731,7 +668,7 @@ public class InferenceSession { final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(getManager().getProject()); for (InferenceVariable var : vars) { final PsiTypeParameter parameter = var.getParameter(); - final PsiTypeParameter copy = elementFactory.createTypeParameterFromText(parameter.getName(), null); + final PsiTypeParameter copy = elementFactory.createTypeParameterFromText("z" + parameter.getName(), null); final PsiType lub = getLowerBound(var, substitutor); final PsiType glb = getUpperBound(var, substitutor); final InferenceVariable zVariable = new InferenceVariable(copy); @@ -744,6 +681,8 @@ public class InferenceSession { zVariable.addBound(lub, InferenceBound.LOWER); } myInferenceVariables.put(copy, zVariable); + allVars.add(zVariable); + var.addBound(elementFactory.createType(copy), InferenceBound.EQ); } myIncorporationPhase.forgetCaptures(vars); if (!myIncorporationPhase.incorporate()) { @@ -762,7 +701,7 @@ public class InferenceSession { }, substitutor); } - private PsiSubstitutor resolveSubset(Collection<InferenceVariable> vars, PsiSubstitutor substitutor, boolean checkResult) { + private PsiSubstitutor resolveSubset(Collection<InferenceVariable> vars, PsiSubstitutor substitutor) { for (InferenceVariable var : vars) { LOG.assertTrue(var.getInstantiation() == PsiType.NULL); final PsiTypeParameter typeParameter = var.getParameter(); @@ -781,7 +720,7 @@ public class InferenceSession { } } - return checkResult ? myIncorporationPhase.checkIncorporated(substitutor, vars) : substitutor; + return substitutor; } private PsiType getUpperBound(InferenceVariable var, PsiSubstitutor substitutor) { @@ -872,7 +811,7 @@ public class InferenceSession { } //resolve input variables - PsiSubstitutor substitutor = resolveSubset(varsToResolve, mySiteSubstitutor, true); + PsiSubstitutor substitutor = resolveSubset(varsToResolve, mySiteSubstitutor); if (substitutor == null) { return false; 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 a67b64eea669..a629175b9d48 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 @@ -48,17 +48,6 @@ public class CheckedExceptionCompatibilityConstraint extends InputOutputConstrai if (!PsiPolyExpressionUtil.isPolyExpression(myExpression)) { return true; } - if (myExpression instanceof PsiCallExpression) { - final PsiExpressionList argumentList = ((PsiCallExpression)myExpression).getArgumentList(); - if (argumentList != null) { - for (PsiExpression expression : argumentList.getExpressions()) { - if (PsiPolyExpressionUtil.isPolyExpression(expression)) { - //todo additional constraints [JDK-8033488] - } - } - } - return true; - } if (myExpression instanceof PsiParenthesizedExpression) { constraints.add(new CheckedExceptionCompatibilityConstraint(((PsiParenthesizedExpression)myExpression).getExpression(), myT)); return true; @@ -122,7 +111,7 @@ public class CheckedExceptionCompatibilityConstraint extends InputOutputConstrai final PsiSubstitutor psiSubstitutor = qualifierResolveResult.getSubstitutor(); final PsiMethod method; if (((PsiMethodReferenceExpression)myExpression).isExact()) { - final PsiElement resolve = ((PsiMethodReferenceExpression)myExpression).resolve(); + final PsiElement resolve = ((PsiMethodReferenceExpression)myExpression).getPotentiallyApplicableMember(); if (resolve instanceof PsiMethod) { method = (PsiMethod)resolve; } else { 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 30628e36beb6..ebcbda6a2926 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 @@ -21,10 +21,13 @@ import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable; import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil; import com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl; import com.intellij.psi.infos.MethodCandidateInfo; +import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NotNull; import java.util.Collection; +import java.util.Iterator; import java.util.List; import java.util.Set; @@ -99,22 +102,51 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm if (typeParams != null) { - for (PsiTypeParameter typeParam : typeParams) { - session.addCapturedVariable(typeParam); - } + final HashSet<PsiTypeParameter> oldBounds = new HashSet<PsiTypeParameter>(session.getTypeParams()); + final boolean sameMethodCall = session.initBounds(typeParams); PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; + final HashSet<InferenceVariable> variables = new HashSet<InferenceVariable>(); + session.collectDependencies(returnType, variables); + final PsiTypeParameter[] params = new PsiTypeParameter[typeParams.length]; + for (int i = 0; i < typeParams.length; i++) { + if (variables.contains(session.getInferenceVariable(typeParams[i]))) { + params[i] = JavaPsiFacade.getElementFactory(myExpression.getProject()).createTypeParameterFromText("copyOf" + myExpression.hashCode() + typeParams[i].getName(), null); + substitutor = substitutor.put(typeParams[i], JavaPsiFacade.getElementFactory(myExpression.getProject()).createType(params[i])); + } + else { + params[i] = typeParams[i]; + } + } + final PsiSubstitutor siteSubstitutor = resolveResult instanceof MethodCandidateInfo && method != null && !method.isConstructor() + ? ((MethodCandidateInfo)resolveResult).getSiteSubstitutor() : PsiSubstitutor.EMPTY; + for (PsiTypeParameter typeParameter : siteSubstitutor.getSubstitutionMap().keySet()) { + substitutor = substitutor.put(typeParameter, substitutor.substitute(siteSubstitutor.substitute(typeParameter))); + } + + final Collection<PsiTypeParameter> params1 = session.getTypeParams(); + final InferenceSession callSession = new InferenceSession(params1.toArray(new PsiTypeParameter[params1.size()]), substitutor, myExpression.getManager(), myExpression); + callSession.initBounds(params); if (method != null) { - //typeParams are already included - final Collection<PsiTypeParameter> params = session.getTypeParams(); - InferenceSession callSession = new InferenceSession(params.toArray(new PsiTypeParameter[params.size()]), resolveResult instanceof MethodCandidateInfo ? ((MethodCandidateInfo)resolveResult).getSiteSubstitutor() - : PsiSubstitutor.EMPTY, myExpression.getManager(), myExpression); final PsiExpression[] args = argumentList.getExpressions(); final PsiParameter[] parameters = method.getParameterList().getParameters(); callSession.initExpressionConstraints(parameters, args, myExpression, method); - callSession.registerConstraints(returnType, myT); - if (callSession.repeatInferencePhases(true)) { - session.liftBounds(callSession.getInferenceVariables()); + } + final boolean accepted = callSession.repeatInferencePhases(true); + if (!accepted) { + //todo return false; + } + callSession.registerConstraints(method != null && !PsiUtil.isRawSubstitutor(method, siteSubstitutor) ? siteSubstitutor.substitute(returnType) : returnType, substitutor.substitute(returnType)); + if (callSession.repeatInferencePhases(true)) { + final Collection<InferenceVariable> inferenceVariables = callSession.getInferenceVariables(); + if (sameMethodCall) { + for (Iterator<InferenceVariable> iterator = inferenceVariables.iterator(); iterator.hasNext(); ) { + InferenceVariable variable = iterator.next(); + if (oldBounds.contains(variable.getParameter())) { + iterator.remove(); + } + } } + session.liftBounds(inferenceVariables); } final PsiType capturedReturnType = myExpression instanceof PsiMethodCallExpression ? PsiMethodCallExpressionImpl.captureReturnType((PsiMethodCallExpression)myExpression, method, returnType, substitutor) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java index 7e2443a8232f..cbb1db809c4a 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java @@ -109,6 +109,11 @@ public class TypeEqualityConstraint implements ConstraintFormula { return true; } + if (myT instanceof PsiCapturedWildcardType && myS instanceof PsiCapturedWildcardType) { + return new TypeEqualityConstraint(((PsiCapturedWildcardType)myT).getWildcard(), + ((PsiCapturedWildcardType)myS).getWildcard()).reduce(session, constraints); + } + return false; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java index 58c29706c1a3..18ff2d110ad9 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java @@ -25,7 +25,6 @@ import com.intellij.psi.tree.TokenSet; import com.intellij.psi.util.PsiUtil; import com.intellij.util.CharTable; import com.intellij.util.IncorrectOperationException; -import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -55,18 +54,19 @@ public class JavaSharedImplUtil { return type; } + // collects annotations bound to C-style arrays private static List<PsiAnnotation[]> collectAnnotations(PsiElement anchor, PsiAnnotation stopAt) { - List<PsiAnnotation[]> annotations = new SmartList<PsiAnnotation[]>(); + List<PsiAnnotation[]> annotations = ContainerUtil.newSmartList(); List<PsiAnnotation> current = null; - boolean stop = false; + boolean found = (stopAt == null), stop = false; for (PsiElement child = anchor.getNextSibling(); child != null; child = child.getNextSibling()) { if (child instanceof PsiComment || child instanceof PsiWhiteSpace) continue; if (child instanceof PsiAnnotation) { - if (current == null) current = new SmartList<PsiAnnotation>(); + if (current == null) current = ContainerUtil.newSmartList(); current.add((PsiAnnotation)child); - if (child == stopAt) stop = true; + if (child == stopAt) found = stop = true; continue; } @@ -80,8 +80,8 @@ public class JavaSharedImplUtil { } } - // stop == true means annotation is misplaced - return stop ? null : annotations; + // annotation is misplaced (either located before the anchor or has no following brackets) + return !found || stop ? null : annotations; } public static void normalizeBrackets(@NotNull PsiVariable variable) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java index f6ba9fdf5af4..918d7fed7237 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -131,7 +131,7 @@ public class JavaTreeGenerator implements TreeGenerator { type = PsiType.getJavaLangObject(manager, GlobalSearchScope.projectScope(manager.getProject())); } - String text = type.getPresentableText(); + String text = type.getCanonicalText(true); PsiJavaParserFacade parserFacade = JavaPsiFacade.getInstance(original.getProject()).getParserFacade(); PsiTypeElement element = parserFacade.createTypeElementFromText(text, original); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ExpressionPsiElement.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ExpressionPsiElement.java index cf40d04ca427..1d8693efc55c 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ExpressionPsiElement.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ExpressionPsiElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,8 @@ public class ExpressionPsiElement extends CompositePsiElement { @Override public void replaceChildInternal(@NotNull ASTNode child, @NotNull TreeElement newElement) { - if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType())) { + if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType()) && + ElementType.EXPRESSION_BIT_SET.contains(newElement.getElementType())) { boolean needParenth = ReplaceExpressionUtil.isNeedParenthesis(child, newElement); if (needParenth) { newElement = SourceUtil.addParenthToReplacedChild(JavaElementType.PARENTH_EXPRESSION, newElement, getManager()); 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 fdd02e86ebb3..084be88d7428 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 @@ -499,6 +499,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase final PsiClass pClass = pResult.getElement(); final PsiSubstitutor receiverSubstitutor = pClass != null ? TypeConversionUtil.getClassSubstitutor(containingClass, pClass, pResult.getSubstitutor()) : null; if (receiverSubstitutor != null) { + if (!method.hasTypeParameters() && signature.getParameterTypes().length == 1) return receiverSubstitutor; psiSubstitutor = receiverSubstitutor; } } @@ -638,20 +639,26 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase } } - checkSpecifics(firstCandidates, - varargs ? MethodCandidateInfo.ApplicabilityLevel.VARARGS : MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY, myLanguageLevel); - - checkSpecifics(secondCandidates, - varargs ? MethodCandidateInfo.ApplicabilityLevel.VARARGS : MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY, myLanguageLevel); - if (myQualifierResolveResult.isReferenceTypeQualified() && getReferenceNameElement() instanceof PsiIdentifier) { //If the first search produces a static method, and no non-static method is applicable for the second search, then the result of the first search is the compile-time declaration. - filterStaticCorrectCandidates(firstCandidates, true); + CandidateInfo candidateInfo = filterStaticCorrectCandidates(firstCandidates, secondCandidates, true); + if (candidateInfo != null) { + return candidateInfo; + } //If the second search produces a non-static method, and no static method is applicable for the first search, then the result of the second search is the compile-time declaration. - filterStaticCorrectCandidates(secondCandidates, false); + candidateInfo = filterStaticCorrectCandidates(secondCandidates, firstCandidates, false); + if (candidateInfo != null) { + return candidateInfo; + } } + checkSpecifics(firstCandidates, + varargs ? MethodCandidateInfo.ApplicabilityLevel.VARARGS : MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY, myLanguageLevel); + + checkSpecifics(secondCandidates, + varargs ? MethodCandidateInfo.ApplicabilityLevel.VARARGS : MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY, myLanguageLevel); + final int acceptedCount = firstCandidates.size() + secondCandidates.size(); if (acceptedCount == 1) { return !firstCandidates.isEmpty() ? firstCandidates.get(0) : secondCandidates.get(0); @@ -684,17 +691,29 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase /** * 15.13.1 */ - private void filterStaticCorrectCandidates(List<CandidateInfo> firstCandidates, + private CandidateInfo filterStaticCorrectCandidates(List<CandidateInfo> firstCandidates, + List<CandidateInfo> secondCandidates, boolean shouldBeStatic) { - for (Iterator<CandidateInfo> iterator = firstCandidates.iterator(); iterator.hasNext(); ) { - final PsiElement element = iterator.next().getElement(); + if (firstCandidates.size() == 1) { + final CandidateInfo candidateInfo = firstCandidates.get(0); + final PsiElement element = candidateInfo.getElement(); if (element instanceof PsiMethod) { final boolean isStatic = ((PsiMethod)element).hasModifierProperty(PsiModifier.STATIC); - if (shouldBeStatic && !isStatic || !shouldBeStatic && isStatic) { - iterator.remove(); + if (shouldBeStatic && isStatic || !shouldBeStatic && !isStatic) { + for (CandidateInfo secondCandidate : secondCandidates) { + final PsiElement psiElement = secondCandidate.getElement(); + if (psiElement instanceof PsiMethod) { + final boolean oppositeStatic = ((PsiMethod)psiElement).hasModifierProperty(PsiModifier.STATIC); + if (shouldBeStatic && !oppositeStatic || !shouldBeStatic && oppositeStatic) { + return null; + } + } + } + return candidateInfo; } } } + return null; } private boolean isCorrectAssignment(PsiType[] signatureParameterTypes2, diff --git a/java/java-tests/testData/codeInsight/completion/normal/MulticaretTyping.java b/java/java-tests/testData/codeInsight/completion/normal/MulticaretTyping.java new file mode 100644 index 000000000000..00d3186f4ef2 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/MulticaretTyping.java @@ -0,0 +1,4 @@ +class Foo {{ + System.out.p<caret> + System.out.p<caret> +}} diff --git a/java/java-tests/testData/codeInsight/completion/normal/MulticaretTyping_after.java b/java/java-tests/testData/codeInsight/completion/normal/MulticaretTyping_after.java new file mode 100644 index 000000000000..87debd854955 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/MulticaretTyping_after.java @@ -0,0 +1,4 @@ +class Foo {{ + System.out.append(<caret>) + System.out.append(<caret>) +}} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting6/UnsupportedFeatures7.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting6/UnsupportedFeatures7.java index 506accd112c3..d0d4dbc5324a 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting6/UnsupportedFeatures7.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting6/UnsupportedFeatures7.java @@ -27,7 +27,7 @@ class UnsupportedFeatures { for (String s : args) { System.out.println(s); } List<String> list = - new ArrayList<>(); + new ArrayList<error descr="Diamond types are not supported at this language level"><></error>(); for (String s : list) {} Arrays.asList(""); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondMisc.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondMisc.java index f51647ab0a23..fbbe91649ddb 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondMisc.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondMisc.java @@ -97,14 +97,14 @@ interface I<T> { class FI1 { I<? extends String> i1 = new I<<error descr="Cannot use ''<>'' with anonymous inner classes"></error>>() { @Override - public <error descr="'m()' in 'Anonymous class derived from I' clashes with 'm()' in 'I'; attempting to use incompatible return type">String</error> m() { + public String m() { return null; } }; I<?> i2 = new I<<error descr="Cannot use ''<>'' with anonymous inner classes"></error>>() { @Override - public <error descr="'m()' in 'Anonymous class derived from I' clashes with 'm()' in 'I'; attempting to use incompatible return type">Object</error> m() { + public Object m() { return null; } }; @@ -157,14 +157,14 @@ class ParenthTest<T extends TZ> { class TestWildcardInference { interface A<T> { } - + class B<V> implements A<V> { B(C<V> v) { } } - + class C<E> {} - + class U { void foo() { C<? extends Number> x = null; @@ -202,13 +202,13 @@ class Another { System.out.println(i); - <error descr="Incompatible types. Found: 'Outer2.Inner2<java.lang.String>', required: 'Outer2.Inner2<java.lang.String>'">Outer2<Integer>.Inner2<String> i5 = new Outer2<>().new Inner2<>();</error> + <error descr="Incompatible types. Found: 'Outer2.Inner2<java.lang.String>', required: 'Outer2<java.lang.Integer>.Inner2<java.lang.String>'">Outer2<Integer>.Inner2<String> i5 = new Outer2<>().new Inner2<>();</error> } static Outer m() {return null;} static <T extends Outer> T m1() {return null;} static <T> T m2() {return null;} - + } class TypeParamsExtendsList { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/typeAnnotations.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/typeAnnotations.java index 400a678da1ed..28035c8c1698 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/typeAnnotations.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/typeAnnotations.java @@ -111,6 +111,7 @@ class Outer { int @TA [] a @TA [] <error descr="Annotations are not allowed here">@TA</error> = (p != null ? p : mixedArrays); return a; } + void <error descr="Annotations are not allowed here">@TA</error> misplaced() { } @TA Outer() { } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57413.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57413.java index 7236a9bcec95..de27a241d858 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57413.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57413.java @@ -2,6 +2,6 @@ class A<T> { <T extends A<T>> void foo(T x){} void bar(A<?> x){ - <error descr="Inferred type 'A<capture<?>>' for type parameter 'T' is not within its bound; should extend 'A<A<capture<?>>>'">foo(x)</error>; + <error descr="Inferred type 'capture<?>' for type parameter 'T' is not within its bound; should extend 'A<capture<? extends A<capture<?>>>>'">foo(x)</error>; } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Variance.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Variance.java index 7556292ef538..298a33dcbdf6 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Variance.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Variance.java @@ -142,7 +142,7 @@ class S1 { } void bar(List<? extends S1> k) { - f<error descr="'f(java.util.List<capture<? extends S1>>, capture<? extends S1>)' in 'S1' cannot be applied to '(java.util.List<capture<? extends S1>>, S1)'">(k, k.get(0))</error>; + f<error descr="'f(java.util.List<capture<? extends S1>>, capture<? extends S1>)' in 'S1' cannot be applied to '(java.util.List<capture<? extends S1>>, capture<? extends S1>)'">(k, k.get(0))</error>; } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/LiftedCaptureToOuterCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/LiftedCaptureToOuterCall.java new file mode 100644 index 000000000000..75d3b8ab6123 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/LiftedCaptureToOuterCall.java @@ -0,0 +1,16 @@ +class Test { + + class Foo<K> {} + + void test(Foo<? extends String> p) { + foo(bar(p)) ; + } + + <T> T bar(Foo<T> p) { + return null; + } + + <K> K foo(K p) { + return null; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/NestedCallsSameMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/NestedCallsSameMethod.java index eaafb1b96716..458171f5b51a 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/NestedCallsSameMethod.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/NestedCallsSameMethod.java @@ -1,3 +1,41 @@ +import java.util.List; + +import java.util.function.Function; + +abstract class Main2 { + void address(Foo sa) { + String ds = foobar(foobar(sa, Foo::getBar), Bar ::getName); + Function<Foo, Bar> f = null; + String ds1 = foobar(foobar(sa, f), null); + } + + abstract <T, V> V foobar(T t, Function<T, V> mapper); + + class Foo { + Bar getBar() { + return new Bar(); + } + } + + class Bar { + String getName(){ + return null; + } + } +} + + +class Main0 { + <T> List<T> foo(T t){ + return null; + } + + { + foo(foo("")); + } +} + + class Main { static <T> T foo(T t) { return null; } @@ -14,6 +52,6 @@ class Main1 { static <B> B bar(B t) { return null;} static { - long l = foo(bar(1)); + //long l = foo(bar(1)); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SiteSubstitutionForReturnConstraint.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SiteSubstitutionForReturnConstraint.java new file mode 100644 index 000000000000..ca5ad38ddfab --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SiteSubstitutionForReturnConstraint.java @@ -0,0 +1,21 @@ +import java.util.function.Function; +import java.util.stream.Collector; + +class Collectors { + + public static <A,R,RR> void collectingAndThen(Function<R, RR> finisher, Function<A, R> finisher1) { + Function<A, RR> f = finisher1.andThen(finisher); + } + +} + + +class Collectors1 { + public static<T,A,R,RR> Collector<T,A,RR> collectingAndThen(Function<R, RR> finisher, Function<A, R> function) { + return factory(function.andThen(finisher)); + } + + static <Ts, As, Rs> Collector<Ts, As, Rs> factory(Function<As, Rs> f) { + return null; + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeAmbiguity.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeAmbiguity.java index 8ee9852f366f..70a6e70c310c 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeAmbiguity.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeAmbiguity.java @@ -40,6 +40,6 @@ class AAmbiguous { } public static void main(Promise<String> helloWorld) { - helloWorld.then<error descr="Ambiguous method call: both 'Promise.then(Function<? super String,Promise<Integer>>)' and 'Promise.then(AsyncFunction<? super String,Promise<Integer>>)' match">(AAmbiguous::calculateLength)</error>; + helloWorld.then<error descr="Ambiguous method call: both 'Promise.then(Function<? super String, Promise<Integer>>)' and 'Promise.then(AsyncFunction<? super String, Promise<Integer>>)' match">(AAmbiguous::calculateLength)</error>; } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java index 84e929697a92..d62afb3fdfcd 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java @@ -21,9 +21,9 @@ class Test { } void foo(Foo<String> as, final Foo<Character> ac) { - boolean b1 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character,Boolean>)' and 'Foo.forAll(II<Character,String>)' match">(c -> false)</error>); - String s1 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character,Boolean>)' and 'Foo.forAll(II<Character,String>)' match">(c -> "")</error>); - boolean b2 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character,Boolean>)' and 'Foo.forAll(II<Character,String>)' match">(c -> "")</error>); + boolean b1 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character, Boolean>)' and 'Foo.forAll(II<Character, String>)' match">(c -> false)</error>); + String s1 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character, Boolean>)' and 'Foo.forAll(II<Character, String>)' match">(c -> "")</error>); + boolean b2 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character, Boolean>)' and 'Foo.forAll(II<Character, String>)' match">(c -> "")</error>); String s2 = as.forAll2(s -> ac.forAll2(<error descr="Incompatible return type boolean in lambda expression">c -> false</error>)); boolean b3 = as.forAll((I<String, Boolean>)s -> ac.forAll((I<Character, Boolean>)<error descr="Incompatible return type String in lambda expression">c -> ""</error>)); String s3 = as.forAll((II<String, String>)s -> ac.forAll((II<Character, String>)<error descr="Incompatible return type boolean in lambda expression">c -> false</error>)); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/DefaultMethodOverrideEquivalentObject.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/DefaultMethodOverrideEquivalentObject.java index cb671b7cd6c0..84b2259286fa 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/DefaultMethodOverrideEquivalentObject.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/DefaultMethodOverrideEquivalentObject.java @@ -2,4 +2,5 @@ interface A { default String <error descr="Default method 'toString' overrides a member of 'java.lang.Object'">toString</error>() { return ""; } + default void finalize() throws Throwable { } }
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/AccessModifiers.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/AccessModifiers.java index 40811fd1f7a7..bc235b224c31 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/AccessModifiers.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/AccessModifiers.java @@ -29,7 +29,7 @@ class AlienTest { <error descr="Incompatible types. Found: '<method reference>', required: 'AlienTest.IInt'">IInt i2 = MyTest::foo;</error> <error descr="Incompatible types. Found: '<method reference>', required: 'AlienTest.IInt'">IInt i3 = MyTest::bar;</error> <error descr="Incompatible types. Found: '<method reference>', required: 'AlienTest.IIntInt'">IIntInt i4 = MyTest::bar;</error> - <error descr="Incompatible types. Found: '<method reference>', required: 'AlienTest.IInt'">IInt i5 = MyTest::baz;</error> + IInt i5 = <error descr="Non-static method cannot be referenced from a static context">MyTest::baz</error>; IInt i6 = <error descr="'foo(int)' is not public in 'MyTest.Foo'. Cannot be accessed from outside package">MyTest.foo::foo</error>; IInt i7 = MyTest.<error descr="'MyTest.Foo' has private access in 'MyTest'">Foo</error>::foo; } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java index 848c423302c6..0696aadf6179 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java @@ -29,7 +29,7 @@ class MyTest { } public static void main(String[] args) { - foo<error descr="Ambiguous method call: both 'MyTest.foo(I1)' and 'MyTest.foo(I2)' match">(Foo::m)</error>; + foo<error descr="Ambiguous method call: both 'MyTest.foo(I2)' and 'MyTest.foo(I3)' match">(Foo::m)</error>; } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/StaticProblems.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/StaticProblems.java index 3375ceb2a090..8d482f2920ab 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/StaticProblems.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/StaticProblems.java @@ -41,14 +41,14 @@ class MyTest1 { static void call2(I2 s) { } static void test1() { - <error descr="Incompatible types. Found: '<method reference>', required: 'MyTest1.I1'">I1 s1 = MyTest1 ::m1;</error> - call1<error descr="'call1(MyTest1.I1)' in 'MyTest1' cannot be applied to '(<method reference>)'">(MyTest1::m1)</error>; + I1 s1 = <error descr="Non-static method cannot be referenced from a static context">MyTest1 ::m1</error>; + call1(<error descr="Non-static method cannot be referenced from a static context">MyTest1::m1</error>); I1 s2 = MyTest1 :: m2; call1(MyTest1::m2); I1 s3 = MyTest1::m3; call1(MyTest1::m3); - <error descr="Incompatible types. Found: '<method reference>', required: 'MyTest1.I1'">I1 s4 = MyTest1::m4;</error> - call1<error descr="'call1(MyTest1.I1)' in 'MyTest1' cannot be applied to '(<method reference>)'">(MyTest1::m4)</error>; + I1 s4 = <error descr="Non-static method cannot be referenced from a static context">MyTest1::m4</error>; + call1(<error descr="Non-static method cannot be referenced from a static context">MyTest1::m4</error>); } static void test2() { @@ -90,14 +90,14 @@ class MyTest2 { static void call2(I2 s) { } static void test1() { - <error descr="Incompatible types. Found: '<method reference>', required: 'MyTest2.I1'">I1 s1 = MyTest2 ::m1;</error> - call1<error descr="'call1(MyTest2.I1)' in 'MyTest2' cannot be applied to '(<method reference>)'">(MyTest2::m1)</error>; + I1 s1 = <error descr="Non-static method cannot be referenced from a static context">MyTest2 ::m1</error>; + call1(<error descr="Non-static method cannot be referenced from a static context">MyTest2::m1</error>); I1 s2 = MyTest2 :: m2; call1(MyTest2::m2); I1 s3 = MyTest2::m3; call1(MyTest2::m3); - <error descr="Incompatible types. Found: '<method reference>', required: 'MyTest2.I1'">I1 s4 = MyTest2::m4;</error> - call1<error descr="'call1(MyTest2.I1)' in 'MyTest2' cannot be applied to '(<method reference>)'">(MyTest2::m4)</error>; + I1 s4 = <error descr="Non-static method cannot be referenced from a static context">MyTest2::m4</error>; + call1(<error descr="Non-static method cannot be referenced from a static context">MyTest2::m4</error>); } static void test2() { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/Varargs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/Varargs.java index 66f4e0701b4b..e521df2c2d40 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/Varargs.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/Varargs.java @@ -55,7 +55,7 @@ class MyTest { { - <error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i_1 = MyTest::_1;</error> + I1 i_1 = <error descr="Non-static method cannot be referenced from a static context">MyTest::_1</error>; <error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i_2 = MyTest::_2;</error> <error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i_3 = MyTest::_3;</error> <error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i_4 = MyTest::_4;</error> diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/VarargsInReceiverPosition.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/VarargsInReceiverPosition.java index f6c1e3f67c0e..cf2151dc76d8 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/VarargsInReceiverPosition.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/VarargsInReceiverPosition.java @@ -3,7 +3,7 @@ import java.util.*; class Test { void test() { Comparator<Test> r2 = Test::yyy; - <error descr="Incompatible types. Found: '<method reference>', required: 'Comparator1<Test>'">Comparator1<Test> c1 = Test::yyy;</error> + Comparator1<Test> c1 = <error descr="Non-static method cannot be referenced from a static context">Test::yyy</error>; <error descr="Incompatible types. Found: '<method reference>', required: 'Comparator1<Test>'">Comparator1<Test> c2 = Test::xxx;</error> } int yyy(Test... p) { return 1; } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/DiamondInLambdaReturn.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/DiamondInLambdaReturn.java new file mode 100644 index 000000000000..8f547d2038ba --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/DiamondInLambdaReturn.java @@ -0,0 +1,9 @@ +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +class Test { + Set<String> collect(Stream<String> map){ + return map.collect(Collectors.toCollection(() -> new LinkedHashSet<>())); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA118965.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA118965.java new file mode 100644 index 000000000000..207a091eb3c6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA118965.java @@ -0,0 +1,37 @@ +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Stream; + +import static java.util.Arrays.asList; + +class Test { + + public static void main(String[] args) { + + List<String> list = new ArrayList<>(); // JDK 7 diamond operator + list.add("aaa"); + list.add("bb"); + list.add("cccc"); + list.add("dd"); + list.add("e"); + + schwartz(list.stream(), s -> s.length()) + .forEach(x -> { System.out.println(x); }); + } + + public static<T, R extends Comparable<? super R>> Stream<T> schwartz(Stream<T> stream, Function<T, R> f) { + + // class Pair - type of second element of pair must be Comparable + final class Pair<F, S extends Comparable<? super S>> { + public final F first; + public final S second; + public Pair(F first, S second){ this.first = first; this.second = second; } + } + + return stream + .map(t -> new Pair<>(t, f.apply(t))) + .sorted((p1, p2) -> p1.second.compareTo(p2.second)) + .map(p -> p.first); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/PotentialApplicability.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/PotentialApplicability.java index ab7614c23c55..18f5026255c6 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/PotentialApplicability.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/PotentialApplicability.java @@ -53,7 +53,7 @@ class Test { Test s1 = staticCall(Test::n0); Test s2 = staticCall(Test::n1); Test s3 = staticCall<error descr="Cannot resolve method 'staticCall(<method reference>)'">(Test::n2)</error>; - Test s4 = staticCall<error descr="Ambiguous method call: both 'Test.staticCall(I1<Test>)' and 'Test.staticCall(I2<Test,String>)' match">(Test::n01)</error>; - Test s5 = staticCall<error descr="Ambiguous method call: both 'Test.staticCall(I1<Test>)' and 'Test.staticCall(I2<Test,String>)' match">(Test::n012)</error>; + Test s4 = staticCall<error descr="Ambiguous method call: both 'Test.staticCall(I1<Test>)' and 'Test.staticCall(I2<Test, String>)' match">(Test::n01)</error>; + Test s5 = staticCall<error descr="Ambiguous method call: both 'Test.staticCall(I1<Test>)' and 'Test.staticCall(I2<Test, String>)' match">(Test::n012)</error>; } }
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/ReturnTypeCheckForRawReceiver.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/ReturnTypeCheckForRawReceiver.java new file mode 100644 index 000000000000..853b02ada009 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/ReturnTypeCheckForRawReceiver.java @@ -0,0 +1,15 @@ +class Test { + + static class Foo<X> { + X m() { return null;} + } + + interface I { + Foo<Object> _i(Foo<String> fs); + } + + static void foo(I i) { } + { + foo(<error descr="Bad return type in method reference: cannot convert java.lang.String to Test.Foo<java.lang.Object>">Foo::m</error>); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/StaticNonStaticReferenceTypeAmbiguity.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/StaticNonStaticReferenceTypeAmbiguity.java new file mode 100644 index 000000000000..7430c7c889e9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/StaticNonStaticReferenceTypeAmbiguity.java @@ -0,0 +1,15 @@ +class Test { + + interface I { + void m(Test rec, String s); + } + + void m(Test t, String s) {} + void m(String s) {} + + static void m(Test t, Object s) {} + + static void test() { + <error descr="Incompatible types. Found: '<method reference>', required: 'Test.I'">I i = Test::m;</error> + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/LambdaFormalParamTypesParametrization.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/LambdaFormalParamTypesParametrization.java new file mode 100644 index 000000000000..0dbcc3e35fec --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/LambdaFormalParamTypesParametrization.java @@ -0,0 +1,10 @@ +import java.util.function.Function; + +class Test { + + <U, V> void foo(Function<U, ? extends V> m) {} + + { + foo((String e) -> e.length()); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/NonWildcardParametrization.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/NonWildcardParametrization.java new file mode 100644 index 000000000000..fa9df550e936 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/NonWildcardParametrization.java @@ -0,0 +1,108 @@ +import java.util.List; + +class SimpleDependency { + + interface I<R extends U, U> { + R m(); + } + + { + I<? extends String, ? extends String> k = () -> null; + I<? extends String, String> k1 = () -> null; + I<? extends List<String>, List<String>> k2 = () -> null; + I<? extends List<String>, ? extends List<String>> k3 = () -> null; + I<? extends List<? extends String>, ? extends List<String>> k4 = <error descr="Cannot infer functional interface type">() -> null</error>; + I<? extends List<? extends String>, List<? extends String>> k5 = () -> null; + I<? extends List<? extends String>, ? extends List<? extends String>> k6 = () -> null; + + I<? super String, String> s = () -> null; + I<? super List<String>, List<? extends String>> s1 = () -> null; + } +} + +class NoDependency { + interface I<T, U> { + T m(); + } + + { + I<? extends String, ? extends String> k = () -> null; + } +} + +class ExtendsList { + interface I<R extends List<T>, T> { + R m(); + } + + { + I<?, ? extends String> n = <error descr="Cannot infer functional interface type">() -> null</error>; + I<?, ?> n1 = <error descr="Cannot infer functional interface type">() -> null</error>; + I<?, String> n2 = <error descr="Cannot infer functional interface type">() -> null</error>; + + + I<? extends List<?>, String> e1 = <error descr="Cannot infer functional interface type">() -> null</error>; + I<? extends List<?>, ?> e2 = <error descr="Cannot infer functional interface type">() -> null</error>; + I<? extends List<String>, ? extends String> e3 = () -> null; + I<? extends List<? extends String>, ? extends String> e4 = <error descr="Cannot infer functional interface type">() -> null</error>; + + I<? super List<String>, ? extends String> s1 = () -> null; + I<? super List<String>, String> s2 = () -> null; + } +} + +class MultipleBounds { + interface I<R extends List<T> & Comparable<T>, T> { + R m(); + } + + interface LC<K> extends List<K>, Comparable<K> {} + + { + I<?, String> n = <error descr="Cannot infer functional interface type">() -> null</error>; + + I<? extends List<String>, ? extends String> e1 = <error descr="Cannot infer functional interface type">() -> null</error>; + I<? extends Comparable<String>, ? extends String> e2 = <error descr="Cannot infer functional interface type">() -> null</error>; + I<? extends LC<String>, ? extends String> e3 = () -> null; + I<? extends LC<String>, String> e4 = () -> null; + I<? extends LC<? extends String>, String> e5 = <error descr="Cannot infer functional interface type">() -> null</error>; + } +} + +class FirstIndependentBound { + interface I<R extends List<String> & Comparable<T>, T> { + R m(); + } + + interface LC<K> extends List<String>, Comparable<K> {} + + { + I<?, String> n = <error descr="Cannot infer functional interface type">() -> null</error>; + + I<? extends List<String>, ? extends String> e1 = <error descr="Cannot infer functional interface type">() -> null</error>; + I<? extends Comparable<String>, ? extends String> e2 = () -> null; + I<? extends LC<String>, ? extends String> e3 = () -> null; + I<? extends LC<String>, String> e4 = () -> null; + I<? extends LC<? extends String>, String> e5 = <error descr="Cannot infer functional interface type">() -> null</error>; + } +} + + +class SecondIndependentBound { + interface I<R extends List<T> & Comparable<String>, T> { + R m(); + } + + interface LC<K> extends List<String>, Comparable<K> {} + + { + I<?, String> n = <error descr="Cannot infer functional interface type">() -> null</error>; + + I<? extends List<String>, ? extends String> e1 = () -> null; + I<? extends Comparable<String>, ? extends String> e2 = <error descr="Cannot infer functional interface type">() -> null</error>; + I<? extends LC<String>, ? extends String> e3 = () -> null; + I<? extends LC<String>, String> e4 = () -> null; + I<? extends LC<? extends String>, String> e5 = <error descr="Cannot infer functional interface type">() -> null</error>; + I<? extends LC<? extends String>, ? extends String> e6 = <error descr="Cannot infer functional interface type">() -> null</error>; + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/PrimitiveParameterTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/PrimitiveParameterTypes.java new file mode 100644 index 000000000000..f339392c1bee --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/PrimitiveParameterTypes.java @@ -0,0 +1,13 @@ +class IDEA100385 { + void foo(N<Double> n){ + n.forEach((<error descr="Incompatible parameter types in lambda expression">double e</error>) -> { }); + } + static interface N<E> { + void forEach(Consumer<? extends E> consumer); + } + + interface Consumer<T> { + public void accept(T t); + } + +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/afterEnumConstantWithoutClassInitializer.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/afterEnumConstantWithoutClassInitializer.java index 9ae8bed1d285..2369d9c9d05d 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/afterEnumConstantWithoutClassInitializer.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/afterEnumConstantWithoutClassInitializer.java @@ -1,9 +1,11 @@ // "Implement Methods" "true" enum E { - A { - public void foo() { - - } - }; - abstract void foo(); + A { + @Override + public int foo() { + return 0; + } + }; + + public abstract int foo(); }
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/afterIDEA108454.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/afterIDEA108454.java new file mode 100644 index 000000000000..a7e8482f6d42 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/afterIDEA108454.java @@ -0,0 +1,17 @@ +// "Implement Methods" "true" +class Test { + class A<T> { + public class Inner { } + } + + interface B<T> { + T foo(); + } + + class D implements B<A<String>.Inner> { + @Override + public A<String>.Inner foo() { + return null; + } + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/beforeEnumConstantWithoutClassInitializer.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/beforeEnumConstantWithoutClassInitializer.java index 92bbb6aea212..518de23ab0c6 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/beforeEnumConstantWithoutClassInitializer.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/beforeEnumConstantWithoutClassInitializer.java @@ -1,5 +1,6 @@ // "Implement Methods" "true" enum E { - <caret>A; - public abstract void foo(); + <caret>A; + + public abstract int foo(); }
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/beforeIDEA108454.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/beforeIDEA108454.java new file mode 100644 index 000000000000..32e8e5b5f4f4 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/beforeIDEA108454.java @@ -0,0 +1,12 @@ +// "Implement Methods" "true" +class Test { + class A<T> { + public class Inner { } + } + + interface B<T> { + T foo(); + } + + <caret>class D implements B<A<String>.Inner> { } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayList.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayList.java new file mode 100644 index 000000000000..aef9e753f716 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayList.java @@ -0,0 +1,15 @@ +// "Replace with collect" "true" +import java.util.*; +import java.util.stream.Collectors; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List<Person> persons){ + List<String> names = persons.stream().map(Person::getName).collect(Collectors.toList()); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListAndFilter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListAndFilter.java new file mode 100644 index 000000000000..4467078950cd --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListAndFilter.java @@ -0,0 +1,15 @@ +// "Replace with collect" "true" +import java.util.*; +import java.util.stream.Collectors; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List<Person> persons){ + List<String> names = persons.stream().filter(person -> person != null).map(Person::getName).collect(Collectors.toList()); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListLambda.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListLambda.java new file mode 100644 index 000000000000..e1517740be28 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListLambda.java @@ -0,0 +1,15 @@ +// "Replace with collect" "true" +import java.util.*; +import java.util.stream.Collectors; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List<Person> persons){ + List<String> names = persons.stream().map(person -> "name: " + person.getName()).collect(Collectors.toList()); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSet.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSet.java new file mode 100644 index 000000000000..022b8e3ae576 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSet.java @@ -0,0 +1,15 @@ +// "Replace with collect" "true" +import java.util.*; +import java.util.stream.Collectors; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List<Person> persons){ + Set<String> names = persons.stream().map(Person::getName).collect(Collectors.toSet()); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSetFieldInitializer.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSetFieldInitializer.java new file mode 100644 index 000000000000..edd903ab1769 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSetFieldInitializer.java @@ -0,0 +1,16 @@ +// "Replace with collect" "true" +import java.util.*; +import java.util.stream.Collectors; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + Set<String> names = new HashSet<>(); + void collectNames(List<Person> persons){ + names.addAll(persons.stream().map(Person::getName).collect(Collectors.toList())); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectLinkedHashSet.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectLinkedHashSet.java new file mode 100644 index 000000000000..6bb6839b0cea --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectLinkedHashSet.java @@ -0,0 +1,15 @@ +// "Replace with collect" "true" +import java.util.*; +import java.util.stream.Collectors; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List<Person> persons){ + Set<String> names = persons.stream().map(Person::getName).collect(Collectors.toCollection(() -> new LinkedHashSet<>())); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSelfCollection.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSelfCollection.java new file mode 100644 index 000000000000..676c127d4a6f --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSelfCollection.java @@ -0,0 +1,15 @@ +// "Replace with collect" "true" +import java.util.*; +import java.util.stream.Collectors; + +public abstract class Collect implements Collection<String>{ + class Person { + String getName() { + return ""; + } + } + + void collectNames(List<Person> persons){ + addAll(persons.stream().map(Person::getName).collect(Collectors.toList())); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSetParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSetParameter.java new file mode 100644 index 000000000000..c8201c9b486e --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSetParameter.java @@ -0,0 +1,15 @@ +// "Replace with collect" "true" +import java.util.*; +import java.util.stream.Collectors; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List<Person> persons, Set<String> names){ + names.addAll(persons.stream().map(Person::getName).collect(Collectors.toList())); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterNoBraces.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterNoBraces.java new file mode 100644 index 000000000000..ab67b49343ca --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterNoBraces.java @@ -0,0 +1,10 @@ +// "Replace with forEach" "true" +import java.util.ArrayList; +import java.util.List; + +class Sample { + List<String> foo = new ArrayList<>(); + { + foo.stream().filter(s -> s != null).forEach(System.out::println); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterNormalNoBraces.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterNormalNoBraces.java new file mode 100644 index 000000000000..b7c6bdeca41d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterNormalNoBraces.java @@ -0,0 +1,10 @@ +// "Replace with forEach" "true" +import java.util.ArrayList; +import java.util.List; + +class Sample { + List<String> foo = new ArrayList<>(); + { + foo.forEach(System.out::println); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayList.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayList.java new file mode 100644 index 000000000000..3114dd720dd3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayList.java @@ -0,0 +1,17 @@ +// "Replace with collect" "true" +import java.util.*; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List<Person> persons){ + List<String> names = new ArrayList<>(); + for (Person person : pers<caret>ons) { + names.add(person.getName()); + } + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListAndFilter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListAndFilter.java new file mode 100644 index 000000000000..9a671cbafd0b --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListAndFilter.java @@ -0,0 +1,19 @@ +// "Replace with collect" "true" +import java.util.*; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List<Person> persons){ + List<String> names = new ArrayList<>(); + for (Person person : pers<caret>ons) { + if (person != null) { + names.add(person.getName()); + } + } + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListLambda.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListLambda.java new file mode 100644 index 000000000000..434c2c5a1bec --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListLambda.java @@ -0,0 +1,17 @@ +// "Replace with collect" "true" +import java.util.*; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List<Person> persons){ + List<String> names = new ArrayList<>(); + for (Person person : pers<caret>ons) { + names.add("name: " + person.getName()); + } + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectHashSet.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectHashSet.java new file mode 100644 index 000000000000..9e1e0e52659d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectHashSet.java @@ -0,0 +1,17 @@ +// "Replace with collect" "true" +import java.util.*; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List<Person> persons){ + Set<String> names = new HashSet<>(); + for (Person person : pers<caret>ons) { + names.add(person.getName()); + } + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectHashSetFieldInitializer.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectHashSetFieldInitializer.java new file mode 100644 index 000000000000..44f39e19f3dc --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectHashSetFieldInitializer.java @@ -0,0 +1,17 @@ +// "Replace with collect" "true" +import java.util.*; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + Set<String> names = new HashSet<>(); + void collectNames(List<Person> persons){ + for (Person person : pers<caret>ons) { + names.add(person.getName()); + } + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectLinkedHashSet.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectLinkedHashSet.java new file mode 100644 index 000000000000..f3ffecc179d0 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectLinkedHashSet.java @@ -0,0 +1,17 @@ +// "Replace with collect" "true" +import java.util.*; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List<Person> persons){ + Set<String> names = new LinkedHashSet<>(); + for (Person person : pers<caret>ons) { + names.add(person.getName()); + } + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSelfCollection.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSelfCollection.java new file mode 100644 index 000000000000..1dbed313c132 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSelfCollection.java @@ -0,0 +1,16 @@ +// "Replace with collect" "true" +import java.util.*; + +public abstract class Collect implements Collection<String>{ + class Person { + String getName() { + return ""; + } + } + + void collectNames(List<Person> persons){ + for (Person person : pers<caret>ons) { + add(person.getName()); + } + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSetParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSetParameter.java new file mode 100644 index 000000000000..f7287c4b9a56 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSetParameter.java @@ -0,0 +1,16 @@ +// "Replace with collect" "true" +import java.util.*; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List<Person> persons, Set<String> names){ + for (Person person : pers<caret>ons) { + names.add(person.getName()); + } + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFilterNoBraces.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFilterNoBraces.java new file mode 100644 index 000000000000..8c712761fb28 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFilterNoBraces.java @@ -0,0 +1,12 @@ +// "Replace with forEach" "true" +import java.util.ArrayList; +import java.util.List; + +class Sample { + List<String> foo = new ArrayList<>(); + { + for (String s : fo<caret>o) { + if (s != null) System.out.println(s); + } + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeNormalNoBraces.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeNormalNoBraces.java new file mode 100644 index 000000000000..0ad984469b06 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeNormalNoBraces.java @@ -0,0 +1,10 @@ +// "Replace with forEach" "true" +import java.util.ArrayList; +import java.util.List; + +class Sample { + List<String> foo = new ArrayList<>(); + { + for (String s : fo<caret>o) System.out.println(s); + } +} diff --git a/java/java-tests/testData/codeInsight/gotosuper/Lambda.after.java b/java/java-tests/testData/codeInsight/gotosuper/Lambda.after.java new file mode 100644 index 000000000000..2fe10c280c86 --- /dev/null +++ b/java/java-tests/testData/codeInsight/gotosuper/Lambda.after.java @@ -0,0 +1,9 @@ +interface I { + void <caret>run(); +} + +class Foo { + { + I i = () -> {}; + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/gotosuper/Lambda.java b/java/java-tests/testData/codeInsight/gotosuper/Lambda.java new file mode 100644 index 000000000000..26c024317a1d --- /dev/null +++ b/java/java-tests/testData/codeInsight/gotosuper/Lambda.java @@ -0,0 +1,9 @@ +interface I { + void run(); +} + +class Foo { + { + I i = ()<caret> -> {}; + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/gotosuper/LambdaMarker.java b/java/java-tests/testData/codeInsight/gotosuper/LambdaMarker.java new file mode 100644 index 000000000000..26c024317a1d --- /dev/null +++ b/java/java-tests/testData/codeInsight/gotosuper/LambdaMarker.java @@ -0,0 +1,9 @@ +interface I { + void run(); +} + +class Foo { + { + I i = ()<caret> -> {}; + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/fileEditorManager/src/Bar.java b/java/java-tests/testData/fileEditorManager/src/Bar.java new file mode 100644 index 000000000000..4843c680a616 --- /dev/null +++ b/java/java-tests/testData/fileEditorManager/src/Bar.java @@ -0,0 +1,5 @@ +public class Bar { + public String doIt() { + return ""; + } +} diff --git a/java/java-tests/testData/psi/shortenClassRefs/TypeAnnotatedRef.java b/java/java-tests/testData/psi/shortenClassRefs/TypeAnnotatedRef.java index b06887668d65..ded427d4aef0 100644 --- a/java/java-tests/testData/psi/shortenClassRefs/TypeAnnotatedRef.java +++ b/java/java-tests/testData/psi/shortenClassRefs/TypeAnnotatedRef.java @@ -1,15 +1,12 @@ -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.*; - -@Target({TYPE_USE}) @interface TA { } +import pkg.TA; class Outer { class Middle { class Inner { void m1(Outer.Middle.Inner p) { } - void m2(@TA Outer.Middle.Inner p) { } - void m3(Outer.@TA Middle.Inner p) { } - void m4(Outer.Middle.@TA @TA Inner p) { } + void m2(@pkg.TA Outer.Middle.Inner p) { } + void m3(Outer.@pkg.TA Middle.Inner p) { } + void m4(Outer.Middle.@pkg.TA @pkg.TA Inner p) { } } } } diff --git a/java/java-tests/testData/psi/shortenClassRefs/TypeAnnotatedRef_after.java b/java/java-tests/testData/psi/shortenClassRefs/TypeAnnotatedRef_after.java index 1c4c8d4a3ec5..fab10a32c52f 100644 --- a/java/java-tests/testData/psi/shortenClassRefs/TypeAnnotatedRef_after.java +++ b/java/java-tests/testData/psi/shortenClassRefs/TypeAnnotatedRef_after.java @@ -1,7 +1,4 @@ -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.*; - -@Target({TYPE_USE}) @interface TA { } +import pkg.TA; class Outer { class Middle { diff --git a/java/java-tests/testData/psi/shortenClassRefs/pkg/TA.java b/java/java-tests/testData/psi/shortenClassRefs/pkg/TA.java new file mode 100644 index 000000000000..abe2aca8d7ac --- /dev/null +++ b/java/java-tests/testData/psi/shortenClassRefs/pkg/TA.java @@ -0,0 +1,6 @@ +package pkg; + +import java.lang.annotation.*; + +@Target({ElementType.TYPE_USE}) +@interface TA { } diff --git a/java/java-tests/testData/refactoring/introduceVariable/genericWithTwoParameters/after/Client.java b/java/java-tests/testData/refactoring/introduceVariable/genericWithTwoParameters/after/Client.java index 38d94b3a880b..c98b7fa857fc 100644 --- a/java/java-tests/testData/refactoring/introduceVariable/genericWithTwoParameters/after/Client.java +++ b/java/java-tests/testData/refactoring/introduceVariable/genericWithTwoParameters/after/Client.java @@ -2,6 +2,6 @@ import util.Pair; class Client { void method() { - Pair<String, Pair<Integer,Boolean>> p = PairProvider.getPair(); + Pair<String, Pair<Integer, Boolean>> p = PairProvider.getPair(); } }
\ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/AddAnnotationFixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/AddAnnotationFixTest.java index 231a0cd45c0a..ec8b8dd49284 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/AddAnnotationFixTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/AddAnnotationFixTest.java @@ -27,7 +27,6 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.ex.PathManagerEx; import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.module.Module; @@ -51,6 +50,7 @@ import com.intellij.testFramework.PsiTestUtil; import com.intellij.testFramework.UsefulTestCase; import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; import com.intellij.testFramework.fixtures.*; +import com.intellij.util.ObjectUtils; import com.intellij.util.messages.MessageBusConnection; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -122,13 +122,7 @@ public class AddAnnotationFixTest extends UsefulTestCase { @NotNull private PsiModifierListOwner getOwner() { - CaretModel caretModel = myFixture.getEditor().getCaretModel(); - int position = caretModel.getOffset(); - PsiElement element = myFixture.getFile().findElementAt(position); - assert element != null; - PsiModifierListOwner container = AddAnnotationPsiFix.getContainer(element); - assert container != null; - return container; + return ObjectUtils.assertNotNull(AddAnnotationPsiFix.getContainer(myFixture.getFile(), myFixture.getCaretOffset())); } private void startListening(@NotNull final List<Trinity<PsiModifierListOwner, String, Boolean>> expectedSequence) { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/ImplementMethodsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/ImplementMethodsTest.java index b5ab59a09c2a..6fd655344758 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/ImplementMethodsTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/ImplementMethodsTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,13 +15,12 @@ */ package com.intellij.codeInsight; -import com.intellij.codeInsight.daemon.quickFix.LightQuickFixAvailabilityTestCase; +import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase; /** - * User: anna - * Date: 10/7/11 + * @author anna */ -public class ImplementMethodsTest extends LightQuickFixAvailabilityTestCase { +public class ImplementMethodsTest extends LightQuickFixParameterizedTestCase { public void test() throws Exception { doAllTests(); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy index 4e8961dbe192..0b12b544bbfd 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy @@ -52,6 +52,7 @@ import com.intellij.psi.PsiFile import com.intellij.psi.PsiJavaFile import com.intellij.psi.statistics.StatisticsManager import com.intellij.psi.statistics.impl.StatisticsManagerImpl +import com.intellij.testFramework.EditorTestUtil import com.intellij.util.containers.ContainerUtil import org.jetbrains.annotations.NotNull @@ -1141,6 +1142,56 @@ class Foo {{ }}''' } + public void testMulticaret() { + doTestMulticaret """ +class Foo {{ + <selection>t<caret></selection>x; + <selection>t<caret></selection>x; +}}""", '\n', ''' +class Foo {{ + toString()<caret>x; + toString()<caret>x; +}}''' + } + + public void testMulticaretTab() { + doTestMulticaret """ +class Foo {{ + <selection>t<caret></selection>x; + <selection>t<caret></selection>x; +}}""", '\t', ''' +class Foo {{ + toString()<caret>; + toString()<caret>; +}}''' + } + + public void testMulticaretBackspace() { + doTestMulticaret """ +class Foo {{ + <selection>t<caret></selection>; + <selection>t<caret></selection>; +}}""", '\b\t', ''' +class Foo {{ + toString()<caret>; + toString()<caret>; +}}''' + } + + private doTestMulticaret(final String textBefore, final String toType, final String textAfter) { + EditorTestUtil.enableMultipleCarets() + try { + myFixture.configureByText "a.java", textBefore + type 'toStr' + assert lookup + type toType + myFixture.checkResult textAfter + } + finally { + EditorTestUtil.disableMultipleCarets() + } + } + private doTestBlockSelection(final String textBefore, final String toType, final String textAfter) { myFixture.configureByText "a.java", textBefore edt { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy index f07a9635da0c..35b71f8cc33b 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy @@ -1403,6 +1403,33 @@ class Foo {{ } } + public void testPrimitiveSquareBracketWhenMultipleCaretsAreEnabled() { + EditorTestUtil.enableMultipleCarets() + try { + configureByFile("PrimitiveSquareBracket.java"); + type('['); + checkResultByFile("PrimitiveSquareBracket_after.java"); + } + finally { + EditorTestUtil.disableMultipleCarets() + } + } + + public void testMulticaretTyping() { + EditorTestUtil.enableMultipleCarets() + try { + configure() + assert lookup + type('p') + assert lookup + type('\n') + checkResult() + } + finally { + EditorTestUtil.disableMultipleCarets() + } + } + public void "test complete lowercase class name"() { myFixture.addClass("package foo; public class myClass {}") myFixture.configureByText "a.java", """ diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java index 1868d2196d7c..964566fcf5ff 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java @@ -39,6 +39,8 @@ public class AnnotationsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testInapplicable() { doTest(false); } public void testDuplicateAttribute() { doTest(false); } public void testDuplicateTarget() { doTest(false); } + public void testPingPongAnnotationTypesDependencies() { doTest(false);} + public void testClashMethods() { doTest(false);} public void testInvalidPackageAnnotationTarget() { doTest(BASE_PATH + "/" + getTestName(true) + "/package-info.java", false, false); } public void testPackageAnnotationNotInPackageInfo() { doTest(BASE_PATH + "/" + getTestName(true) + "/notPackageInfo.java", false, false); } @@ -46,9 +48,6 @@ public class AnnotationsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testTypeAnnotations() { doTest8(false); } public void testRepeatable() { doTest8(false); } - public void testPingPongAnnotationTypesDependencies() { doTest(false);} - public void testClashMethods() { doTest(false);} - private void doTest(boolean checkWarnings) { setLanguageLevel(LanguageLevel.JDK_1_7); doTest(BASE_PATH + "/" + getTestName(true) + ".java", checkWarnings, false); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ImportHelperTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ImportHelperTest.java index b50052b71750..80448f9d3a96 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ImportHelperTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ImportHelperTest.java @@ -368,7 +368,7 @@ public class ImportHelperTest extends DaemonAnalyzerTestCase { public void testAutoImportOfGenericReference() throws Throwable { - @NonNls final String text = "class S {{ new ArrayList<caret><> }}"; + @NonNls final String text = "class S {{ new ArrayList<caret><String> }}"; configureByText(StdFileTypes.JAVA, text); boolean old = CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY; CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY = true; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FunctionalTypeWildcardParameterizationTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FunctionalTypeWildcardParameterizationTest.java new file mode 100644 index 000000000000..599ae74cd00d --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FunctionalTypeWildcardParameterizationTest.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package 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; + +public class FunctionalTypeWildcardParameterizationTest extends LightDaemonAnalyzerTestCase { + @NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization"; + + public void testNonWildcardParametrization() throws Exception { + doTest(); + } + + public void testLambdaFormalParamTypesParametrization() throws Exception { + doTest(); + } + + public void testPrimitiveParameterTypes() throws Exception { + doTest(); + } + + private void doTest() { + IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable()); + 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/GraphInferenceHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java index 1119a0d6d4df..8af0821571d6 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 @@ -28,7 +28,7 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase doTest(); } - public void _testNestedCallsSameMethod() throws Exception { + public void testNestedCallsSameMethod() throws Exception { doTest(); } @@ -160,6 +160,14 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase doTest(); } + public void testLiftedCaptureToOuterCall() throws Exception { + doTest(); + } + + public void testSiteSubstitutionForReturnConstraint() throws Exception { + doTest(); + } + private void doTest() throws Exception { doTest(false); } 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 89ddef20df0e..826193c90f90 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 @@ -138,6 +138,14 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testDiamondInLambdaReturn() throws Exception { + doTest(); + } + + public void testIDEA118965() throws Exception { + doTest(); + } + private void doTest() { doTest(false); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java index e944269c098b..83f0dfac5c1e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java @@ -173,6 +173,14 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testReturnTypeCheckForRawReceiver() throws Exception { + doTest(); + } + + public void testStaticNonStaticReferenceTypeAmbiguity() throws Exception { + doTest(); + } + private void doTest() { doTest(false); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/navigation/JavaGotoSuperTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/navigation/JavaGotoSuperTest.java new file mode 100644 index 000000000000..313720456ae5 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/navigation/JavaGotoSuperTest.java @@ -0,0 +1,52 @@ +package com.intellij.codeInsight.navigation; + +import com.intellij.JavaTestUtil; +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; +import com.intellij.codeInsight.daemon.LineMarkerInfo; +import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl; +import com.intellij.lang.CodeInsightActions; +import com.intellij.lang.java.JavaLanguage; +import com.intellij.openapi.editor.Document; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class JavaGotoSuperTest extends LightDaemonAnalyzerTestCase { + @NotNull + @Override + protected String getTestDataPath() { + return JavaTestUtil.getJavaTestDataPath(); + } + + protected String getBasePath() { + return "/codeInsight/gotosuper/"; + } + + public void testLambda() throws Throwable { + doTest(); + } + + public void testLambdaMarker() throws Exception { + configureByFile(getBasePath() + getTestName(false) + ".java"); + int offset = myEditor.getCaretModel().getOffset(); + + doHighlighting(); + Document document = getEditor().getDocument(); + List<LineMarkerInfo> markers = DaemonCodeAnalyzerImpl.getLineMarkers(document, getProject()); + for (LineMarkerInfo info : markers) { + if (info.endOffset >= offset && info.startOffset <= offset) { + assertEquals("<html><body>Overrides method in 'I'</body></html>", info.getLineMarkerTooltip()); + return; + } + } + fail("Gutter expected"); + } + + private void doTest() throws Throwable { + configureByFile(getBasePath() + getTestName(false) + ".java"); + final CodeInsightActionHandler handler = CodeInsightActions.GOTO_SUPER.forLanguage(JavaLanguage.INSTANCE); + handler.invoke(getProject(), getEditor(), getFile()); + checkResultByFile(getBasePath() + getTestName(false) + ".after.java"); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/psi/AnnotatedTypeTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/psi/AnnotatedTypeTest.groovy index f186f9e8f5c8..6373bc3ce307 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/psi/AnnotatedTypeTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/psi/AnnotatedTypeTest.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,15 +15,22 @@ */ package com.intellij.codeInsight.psi -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiFile +import com.intellij.pom.java.LanguageLevel +import com.intellij.psi.* +import com.intellij.psi.impl.source.PsiImmediateClassType import com.intellij.testFramework.LightIdeaTestCase -@SuppressWarnings(["GrUnresolvedAccess", "GroovyAssignabilityCheck"]) +@SuppressWarnings("GroovyAssignabilityCheck") class AnnotatedTypeTest extends LightIdeaTestCase { + private PsiFile context + private PsiElementFactory factory + + public void setUp() throws Exception { + super.setUp() + factory = javaFacade.elementFactory + context = createFile("typeCompositionTest.java", """ +package pkg; - public void testTypeComposition() { - PsiFile context = createFile("typeCompositionTest.java", """ import java.lang.annotation.*; import static java.lang.annotation.ElementType.*; @@ -33,31 +40,55 @@ import static java.lang.annotation.ElementType.*; class E1 extends Exception { } class E2 extends Exception { } """) - PsiElement psi + } + + public void testPrimitiveArrayType() { + doTest("@A @TA(1) int @TA(2) [] a", "@pkg.TA(1) int @pkg.TA(2) []", "int[]") + } - psi = javaFacade.elementFactory.createStatementFromText("@A @TA(1) int @TA(2) [] a", context) - assertEquals("@TA(1) int @TA(2) []", psi.declaredElements[0].type.presentableText) + public void testEllipsisType() { + def psi = factory.createParameterFromText("@TA int @TA ... p", context) + assertTypeText(psi.type, "@pkg.TA int @pkg.TA ...", "int...") + } - psi = javaFacade.elementFactory.createStatementFromText("try { } catch (@A @TA(1) E1 | @TA(2) E2 e) { }", context) - assertEquals("@TA(1) E1 | @TA(2) E2", psi.catchBlockParameters[0].type.presentableText) + public void testClassReferenceType() { + doTest("@A @TA(1) String s", "java.lang.@pkg.TA(1) String", "java.lang.String") + doTest("@A java.lang.@TA(1) String s", "java.lang.@pkg.TA(1) String", "java.lang.String") + } - psi = javaFacade.elementFactory.createStatementFromText("@A @TA(1) String @TA(2) [] f @TA(3) []", context) - assertEquals("@TA(1) String @TA(2) [] @TA(3) []", psi.declaredElements[0].type.presentableText) + public void testCStyleArrayType() { + doTest("@A @TA(1) String @TA(2) [] f @TA(3) []", "java.lang.@pkg.TA(1) String @pkg.TA(2) [] @pkg.TA(3) []", "java.lang.String[][]") + } - psi = javaFacade.elementFactory.createStatementFromText("Class<@TA(1) ?> c", context) - assertEquals("Class<@TA(1) ?>", psi.declaredElements[0].type.presentableText) + public void testWildcardType() { + doTest("Class<@TA(1) ?> c", "java.lang.Class<@pkg.TA(1) ?>", "java.lang.Class<?>") + } - psi = javaFacade.elementFactory.createStatementFromText("Class<@TA String> cs = new Class<>()", context) - assertEquals("Class<@TA String>", psi.declaredElements[0].initializer.type.presentableText) + public void testDisjunctionType() { + def psi = factory.createStatementFromText("try { } catch (@A @TA(1) E1 | @TA(2) E2 e) { }", context) + assertTypeText(psi.catchBlockParameters[0].type, "pkg.@pkg.TA(1) E1 | pkg.@pkg.TA(2) E2", "pkg.E1 | pkg.E2") + } - psi = javaFacade.elementFactory.createStatementFromText("@A @TA(1) String s", context) - assertEquals("@TA(1) String", psi.declaredElements[0].type.presentableText) + public void testDiamondType() { + def psi = factory.createStatementFromText("Class<@TA String> cs = new Class<>()", context) + assertTypeText(psi.declaredElements[0].initializer.type, "java.lang.Class<java.lang.@pkg.TA String>", "java.lang.Class<java.lang.String>") + } - psi = javaFacade.elementFactory.createStatementFromText("@A java.lang.@TA(1) String s", context) - assertEquals("@TA(1) String", psi.declaredElements[0].type.presentableText) + public void testImmediateClassType() { + def aClass = javaFacade.findClass(CommonClassNames.JAVA_LANG_OBJECT) + def statement = factory.createStatementFromText("@TA int x", context) + def annotations = statement.declaredElements[0].modifierList.annotations + def type = new PsiImmediateClassType(aClass, PsiSubstitutor.EMPTY, LanguageLevel.JDK_1_8, annotations) + assertTypeText(type, "java.lang.@pkg.TA Object", CommonClassNames.JAVA_LANG_OBJECT) + } - psi = javaFacade.elementFactory.createStatementFromText("Collection<? extends> s", context) - assertEquals("Collection<?>", psi.declaredElements[0].type.presentableText) + private void doTest(String text, String annotated, String canonical) { + def psi = factory.createStatementFromText(text, context) + assertTypeText(psi.declaredElements[0].type, annotated, canonical) } + private static void assertTypeText(PsiType type, String annotated, String canonical) { + assert type.getCanonicalText(true) == annotated + assert type.getCanonicalText(false) == canonical + } } diff --git a/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java b/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java index c2cef13e6ea8..bfd1de796f90 100644 --- a/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java +++ b/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java @@ -194,7 +194,7 @@ public class FindManagerTest extends DaemonAnalyzerTestCase { PsiDirectory psiDirectory = FindInProjectUtil.getPsiDirectory(findModel, myProject); List<UsageInfo> result = new ArrayList<UsageInfo>(); final CommonProcessors.CollectProcessor<UsageInfo> collector = new CommonProcessors.CollectProcessor<UsageInfo>(result); - FindInProjectUtil.findUsages(findModel, psiDirectory, myProject, true, collector, new FindUsagesProcessPresentation(FindInProjectUtil.setupViewPresentation(true, findModel))); + FindInProjectUtil.findUsages(findModel, psiDirectory, myProject, collector, new FindUsagesProcessPresentation(FindInProjectUtil.setupViewPresentation(true, findModel))); return result; } diff --git a/java/java-tests/testSrc/com/intellij/index/IndexTest.java b/java/java-tests/testSrc/com/intellij/index/IndexTest.java index fba5b6e5265d..7770c5e4a1f9 100644 --- a/java/java-tests/testSrc/com/intellij/index/IndexTest.java +++ b/java/java-tests/testSrc/com/intellij/index/IndexTest.java @@ -34,6 +34,7 @@ import com.intellij.testFramework.SkipSlowTestLocally; import com.intellij.util.indexing.MapIndexStorage; import com.intellij.util.indexing.StorageException; import com.intellij.util.io.*; +import org.jetbrains.annotations.NotNull; import java.io.DataInput; import java.io.DataOutput; @@ -113,7 +114,7 @@ public class IndexTest extends IdeaTestCase { private PersistentHashMap<Integer, Collection<String>> createMetaIndex(File metaIndexFile) throws IOException { return new PersistentHashMap<Integer, Collection<String>>(metaIndexFile, new EnumeratorIntegerDescriptor(), new DataExternalizer<Collection<String>>() { @Override - public void save(DataOutput out, Collection<String> value) throws IOException { + public void save(@NotNull DataOutput out, Collection<String> value) throws IOException { DataInputOutputUtil.writeINT(out, value.size()); for (String key : value) { out.writeUTF(key); @@ -121,7 +122,7 @@ public class IndexTest extends IdeaTestCase { } @Override - public Collection<String> read(DataInput in) throws IOException { + public Collection<String> read(@NotNull DataInput in) throws IOException { final int size = DataInputOutputUtil.readINT(in); final List<String> list = new ArrayList<String>(); for (int idx = 0; idx < size; idx++) { diff --git a/java/java-tests/testSrc/com/intellij/index/StringIndex.java b/java/java-tests/testSrc/com/intellij/index/StringIndex.java index a12f58fbf137..7d2dd108ceac 100644 --- a/java/java-tests/testSrc/com/intellij/index/StringIndex.java +++ b/java/java-tests/testSrc/com/intellij/index/StringIndex.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.index; import com.intellij.openapi.util.Factory; @@ -28,7 +43,7 @@ public class StringIndex { myIndex.setInputIdToDataKeysIndex(factory); } - public List<String> getFilesByWord(String word) throws StorageException { + public List<String> getFilesByWord(@NotNull String word) throws StorageException { return myIndex.getData(word).toValueList(); } diff --git a/java/java-tests/testSrc/com/intellij/openapi/editor/impl/JavaFileEditorManagerTest.java b/java/java-tests/testSrc/com/intellij/openapi/editor/impl/JavaFileEditorManagerTest.java new file mode 100644 index 000000000000..2a985b873ee3 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/openapi/editor/impl/JavaFileEditorManagerTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.fileEditor.FileEditorManagerTestCase; +import com.intellij.testFramework.PlatformTestUtil; +import org.jdom.JDOMException; + +import java.io.File; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +/** + * @author Dmitry Avdeev + */ +public class JavaFileEditorManagerTest extends FileEditorManagerTestCase { + + public void testAsyncOpening() throws JDOMException, ExecutionException, InterruptedException, IOException { + openFiles("<component name=\"FileEditorManager\">\n" + + " <leaf>\n" + + " <file leaf-file-name=\"Bar.java\" pinned=\"false\" current=\"true\" current-in-tab=\"true\">\n" + + " <entry file=\"file://$PROJECT_DIR$/src/Bar.java\">\n" + + " <provider selected=\"true\" editor-type-id=\"text-editor\">\n" + + " <state vertical-scroll-proportion=\"0.032882012\" vertical-offset=\"0\" max-vertical-offset=\"517\">\n" + + " <caret line=\"1\" column=\"26\" selection-start=\"45\" selection-end=\"45\" />\n" + + " <folding>\n" + + " <element signature=\"e#69#70#0\" expanded=\"true\" />\n" + + " </folding>\n" + + " </state>\n" + + " </provider>\n" + + " </entry>\n" + + " </file>\n" + + " </leaf>\n" + + " </component>"); + } + + @Override + protected String getTestDataPath() { + return PlatformTestUtil.getCommunityPath().replace(File.separatorChar, '/') + "/java/java-tests/testData/fileEditorManager"; + } +} diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/AbstractJavaFormatterTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/AbstractJavaFormatterTest.java index 58c02ef225b3..ab057c436baa 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/AbstractJavaFormatterTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/AbstractJavaFormatterTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,6 +42,7 @@ import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.util.EnumMap; +import java.util.List; import java.util.Map; /** @@ -51,13 +52,20 @@ import java.util.Map; * @since Apr 27, 2010 6:26:29 PM */ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase { - @NotNull - public static String shiftIndentInside(@NotNull String initial, final int i, boolean shiftEmptyLines) throws IOException { + public static String shiftIndentInside(@NotNull String initial, final int i, boolean shiftEmptyLines) { StringBuilder result = new StringBuilder(initial.length()); - LineReader reader = new LineReader(new ByteArrayInputStream(initial.getBytes())); + List<byte[]> lines; + try { + LineReader reader = new LineReader(new ByteArrayInputStream(initial.getBytes("UTF-8"))); + lines = reader.readLines(); + } + catch (IOException e) { + throw new RuntimeException(e); + } + boolean first = true; - for (byte[] line : reader.readLines()) { + for (byte[] line : lines) { try { if (!first) result.append('\n'); if (line.length > 0 || shiftEmptyLines) { @@ -75,7 +83,6 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase { protected enum Action {REFORMAT, INDENT} - public static JavaCodeStyleSettings getJavaSettings() { return getSettings().getRootSettings().getCustomSettings(JavaCodeStyleSettings.class); } @@ -116,20 +123,15 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase { return rootSettings.getCommonSettings(JavaLanguage.INSTANCE); } - //public static JavaCodeStyleSettings getJavaSettings() { - // CodeStyleSettings rootSettings = CodeStyleSettingsManager.getSettings(getProject()); - // return rootSettings.getCustomSettings(JavaCodeStyleSettings.class); - //} - // public static CommonCodeStyleSettings.IndentOptions getIndentOptions() { return getSettings().getRootSettings().getIndentOptions(StdFileTypes.JAVA); } - public void doTest() throws Exception { + public void doTest() { doTest(getTestName(false) + ".java", getTestName(false) + "_after.java"); } - public void doTest(@NonNls String fileNameBefore, @NonNls String fileNameAfter) throws Exception { + public void doTest(@NonNls String fileNameBefore, @NonNls String fileNameAfter) { doTextTest(Action.REFORMAT, loadFile(fileNameBefore), loadFile(fileNameAfter)); } @@ -137,7 +139,7 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase { doTextTest(Action.REFORMAT, text, textAfter); } - public void doTextTest(@NotNull final Action action, @NotNull final String text, @NotNull String textAfter) throws IncorrectOperationException { + public void doTextTest(@NotNull final Action action, @NotNull String text, @NotNull String textAfter) throws IncorrectOperationException { final PsiFile file = createFile("A.java", text); final PsiDocumentManager manager = PsiDocumentManager.getInstance(getProject()); final Document document = manager.getDocument(file); @@ -204,7 +206,7 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase { return document.getText(); } - public void doMethodTest(@NonNls final String before, @NonNls final String after) throws Exception { + public void doMethodTest(@NonNls final String before, @NonNls final String after) { doTextTest( Action.REFORMAT, "class Foo{\n" + " void foo() {\n" + before + '\n' + " }\n" + "}", @@ -212,7 +214,7 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase { ); } - public void doClassTest(@NonNls final String before, @NonNls final String after) throws Exception { + public void doClassTest(@NonNls final String before, @NonNls final String after) { doTextTest( Action.REFORMAT, "class Foo{\n" + before + '\n' + "}", @@ -220,10 +222,14 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase { ); } - private static String loadFile(String name) throws Exception { + private static String loadFile(String name) { String fullName = BASE_PATH + File.separatorChar + name; - String text = FileUtil.loadFile(new File(fullName)); - text = StringUtil.convertLineSeparators(text); - return text; + try { + String text = FileUtil.loadFile(new File(fullName)); + return StringUtil.convertLineSeparators(text); + } + catch (IOException e) { + throw new RuntimeException(e); + } } } diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterNewLineTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterNewLineTest.java index 038b1d01f0e1..a7473f61e5a4 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterNewLineTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterNewLineTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ import com.intellij.util.IncorrectOperationException; */ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest { - public void testAutomaticElseWrapping() throws Exception { + public void testAutomaticElseWrapping() { getSettings().ELSE_ON_NEW_LINE = true; doMethodTest( @@ -43,7 +43,7 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest { ); } - public void testAutomaticElseUnwrapping() throws Exception { + public void testAutomaticElseUnwrapping() { getSettings().ELSE_ON_NEW_LINE = false; getSettings().KEEP_LINE_BREAKS = true; @@ -60,7 +60,7 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest { ); } - public void testAutomaticCatchWrapping() throws Exception { + public void testAutomaticCatchWrapping() { getSettings().CATCH_ON_NEW_LINE = true; doMethodTest( @@ -75,7 +75,7 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest { ); } - public void testAutomaticCatchUnwrapping() throws Exception { + public void testAutomaticCatchUnwrapping() { getSettings().CATCH_ON_NEW_LINE = false; getSettings().KEEP_LINE_BREAKS = true; @@ -92,7 +92,7 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest { ); } - public void testAutomaticFinallyWrapping() throws Exception { + public void testAutomaticFinallyWrapping() { getSettings().FINALLY_ON_NEW_LINE = true; doMethodTest( @@ -107,7 +107,7 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest { ); } - public void testAutomaticFinallyUnwrapping() throws Exception { + public void testAutomaticFinallyUnwrapping() { getSettings().FINALLY_ON_NEW_LINE = false; getSettings().KEEP_LINE_BREAKS = true; @@ -124,7 +124,7 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest { ); } - public void testAutomaticCatchFinallyUnwrapping() throws Exception { + public void testAutomaticCatchFinallyUnwrapping() { // Inspired by IDEA-47809 getSettings().CATCH_ON_NEW_LINE = false; getSettings().FINALLY_ON_NEW_LINE = false; @@ -144,8 +144,8 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest { "}" ); } - - public void testClassInitializationBlockBracesPlacement() throws Exception { + + public void testClassInitializationBlockBracesPlacement() { // Inspired by IDEA-54191 getSettings().getRootSettings().getIndentOptions(StdFileTypes.JAVA).INDENT_SIZE = 4; getSettings().KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = false; @@ -161,7 +161,7 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest { ); } - public void testBlockOfMethodWithAnnotatedParameter() throws Exception { + public void testBlockOfMethodWithAnnotatedParameter() { // Inspired by IDEA-17870 doClassTest("public Test(@Qualifier(\"blah\") AType blah){}", "public Test(@Qualifier(\"blah\") AType blah) {\n" + "}"); } @@ -193,7 +193,7 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest { ); } - public void testSimpleAnnotatedMethodAndBraceOnNextLineStyle() throws Exception { + public void testSimpleAnnotatedMethodAndBraceOnNextLineStyle() { // Inspired by IDEA-53542 getSettings().METHOD_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; getSettings().KEEP_SIMPLE_METHODS_IN_ONE_LINE = true; diff --git a/java/java-tests/testSrc/com/intellij/psi/impl/source/tree/java/ShortenClassReferencesTest.java b/java/java-tests/testSrc/com/intellij/psi/impl/source/tree/java/ShortenClassReferencesTest.java index e21c18022e1e..4554f93fb20d 100644 --- a/java/java-tests/testSrc/com/intellij/psi/impl/source/tree/java/ShortenClassReferencesTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/impl/source/tree/java/ShortenClassReferencesTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,6 +61,7 @@ public class ShortenClassReferencesTest extends LightCodeInsightFixtureTestCase public void testSCR37254() { doTest(); } public void testTypeAnnotatedRef() { + myFixture.configureByFile("pkg/TA.java"); doTest(); for (PsiParameter parameter : PsiTreeUtil.findChildrenOfType(myFixture.getFile(), PsiParameter.class)) { PsiTypeElement typeElement = parameter.getTypeElement(); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTest.java index 51905419d22c..4f6c44824ab6 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,360 +34,388 @@ import java.util.HashSet; * @author dsl */ public class ChangeSignatureTest extends LightRefactoringTestCase { - public void testSimple() throws Exception { + private PsiElementFactory myFactory; + + public void setUp() throws Exception { + super.setUp(); + myFactory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); + } + + public void testSimple() { doTest(null, null, null, new ParameterInfoImpl[0], new ThrownExceptionInfo[0], false); } - public void testParameterReorder() throws Exception { + public void testParameterReorder() { doTest(null, new ParameterInfoImpl[]{new ParameterInfoImpl(1), new ParameterInfoImpl(0)}, false); } - public void testWarnAboutContract() throws Exception { + public void testWarnAboutContract() { try { doTest(null, new ParameterInfoImpl[]{new ParameterInfoImpl(1), new ParameterInfoImpl(0)}, false); fail("Conflict expected"); } - catch (BaseRefactoringProcessor.ConflictsInTestsException ignored) { - } + catch (BaseRefactoringProcessor.ConflictsInTestsException ignored) { } } - public void testGenericTypes() throws Exception { + public void testGenericTypes() { doTest(null, null, "T", new GenParams() { @Override public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException { - final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); return new ParameterInfoImpl[]{ - new ParameterInfoImpl(-1, "x", factory.createTypeFromText("T", method.getParameterList()), "null"), - new ParameterInfoImpl(-1, "y", factory.createTypeFromText("C<T>", method.getParameterList()), "null") + new ParameterInfoImpl(-1, "x", myFactory.createTypeFromText("T", method.getParameterList()), "null"), + new ParameterInfoImpl(-1, "y", myFactory.createTypeFromText("C<T>", method.getParameterList()), "null") }; } }, false); } - public void testGenericTypesInOldParameters() throws Exception { + public void testGenericTypesInOldParameters() { doTest(null, null, null, new GenParams() { @Override public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException { - final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); - return new ParameterInfoImpl[] { - new ParameterInfoImpl(0, "t", factory.createTypeFromText("T", method), null) + return new ParameterInfoImpl[]{ + new ParameterInfoImpl(0, "t", myFactory.createTypeFromText("T", method), null) }; } }, false); } - public void testTypeParametersInMethod() throws Exception { + public void testTypeParametersInMethod() { doTest(null, null, null, new GenParams() { - @Override - public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException { - final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); - return new ParameterInfoImpl[]{ - new ParameterInfoImpl(-1, "t", factory.createTypeFromText("T", method.getParameterList()), "null"), - new ParameterInfoImpl(-1, "u", factory.createTypeFromText("U", method.getParameterList()), "null"), - new ParameterInfoImpl(-1, "cu", factory.createTypeFromText("C<U>", method.getParameterList()), "null") - }; - } - }, false); + @Override + public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException { + return new ParameterInfoImpl[]{ + new ParameterInfoImpl(-1, "t", myFactory.createTypeFromText("T", method.getParameterList()), "null"), + new ParameterInfoImpl(-1, "u", myFactory.createTypeFromText("U", method.getParameterList()), "null"), + new ParameterInfoImpl(-1, "cu", myFactory.createTypeFromText("C<U>", method.getParameterList()), "null") + }; + } + }, false); } - public void testDefaultConstructor() throws Exception { + public void testDefaultConstructor() { doTest(null, - new ParameterInfoImpl[] { - new ParameterInfoImpl(-1, "j", PsiType.INT, "27") - }, false); + new ParameterInfoImpl[]{ + new ParameterInfoImpl(-1, "j", PsiType.INT, "27") + }, false + ); } - public void testGenerateDelegate() throws Exception { + public void testGenerateDelegate() { doTest(null, - new ParameterInfoImpl[] { + new ParameterInfoImpl[]{ new ParameterInfoImpl(-1, "i", PsiType.INT, "27") - }, true); + }, true + ); } - public void testGenerateDelegateForAbstract() throws Exception { + public void testGenerateDelegateForAbstract() { doTest(null, - new ParameterInfoImpl[] { + new ParameterInfoImpl[]{ new ParameterInfoImpl(-1, "i", PsiType.INT, "27") - }, true); + }, true + ); } - public void testGenerateDelegateWithReturn() throws Exception { + public void testGenerateDelegateWithReturn() { doTest(null, - new ParameterInfoImpl[] { + new ParameterInfoImpl[]{ new ParameterInfoImpl(-1, "i", PsiType.INT, "27") - }, true); + }, true + ); } - public void testGenerateDelegateWithParametersReordering() throws Exception { + public void testGenerateDelegateWithParametersReordering() { doTest(null, - new ParameterInfoImpl[] { + new ParameterInfoImpl[]{ new ParameterInfoImpl(1), new ParameterInfoImpl(-1, "c", PsiType.CHAR, "'a'"), new ParameterInfoImpl(0, "j", PsiType.INT) - }, true); + }, true + ); } - public void testGenerateDelegateConstructor() throws Exception { + public void testGenerateDelegateConstructor() { doTest(null, new ParameterInfoImpl[0], true); } - public void testGenerateDelegateDefaultConstructor() throws Exception { - doTest(null, new ParameterInfoImpl[] { + public void testGenerateDelegateDefaultConstructor() { + doTest(null, new ParameterInfoImpl[]{ new ParameterInfoImpl(-1, "i", PsiType.INT, "27") }, true); } - public void testSCR40895() throws Exception { - doTest(null, new ParameterInfoImpl[] { + public void testSCR40895() { + doTest(null, new ParameterInfoImpl[]{ new ParameterInfoImpl(0, "y", PsiType.INT), new ParameterInfoImpl(1, "b", PsiType.BOOLEAN) }, false); } - public void testJavadocGenericsLink() throws Exception { - doTest(null, new ParameterInfoImpl[] { - new ParameterInfoImpl(-1, "y", JavaPsiFacade.getElementFactory(getProject()).createTypeFromText("java.util.List<java.lang.String>", null)), + public void testJavadocGenericsLink() { + doTest(null, new ParameterInfoImpl[]{ + new ParameterInfoImpl(-1, "y", myFactory.createTypeFromText("java.util.List<java.lang.String>", null)), new ParameterInfoImpl(0, "a", PsiType.BOOLEAN) }, false); } - public void testParamNameSameAsFieldName() throws Exception { - doTest(null, new ParameterInfoImpl[] { + public void testParamNameSameAsFieldName() { + doTest(null, new ParameterInfoImpl[]{ new ParameterInfoImpl(0, "fieldName", PsiType.INT) }, false); } - public void testParamNameNoConflict() throws Exception { + public void testParamNameNoConflict() { doTest(null, new ParameterInfoImpl[]{ new ParameterInfoImpl(0), new ParameterInfoImpl(-1, "b", PsiType.BOOLEAN) }, false); } - public void testParamJavadoc() throws Exception { - doTest(null, new ParameterInfoImpl[] { + public void testParamJavadoc() { + doTest(null, new ParameterInfoImpl[]{ new ParameterInfoImpl(1, "z", PsiType.INT), new ParameterInfoImpl(0, "y", PsiType.INT) }, false); } - public void testParamJavadoc0() throws Exception { - doTest(null, new ParameterInfoImpl[] { + public void testParamJavadoc0() { + doTest(null, new ParameterInfoImpl[]{ new ParameterInfoImpl(1, "z", PsiType.INT), new ParameterInfoImpl(0, "y", PsiType.INT) }, false); } - public void testParamJavadoc1() throws Exception { + public void testParamJavadoc1() { doTest(null, new ParameterInfoImpl[]{ new ParameterInfoImpl(0, "z", PsiType.BOOLEAN) }, false); } - public void testParamJavadoc2() throws Exception { + public void testParamJavadoc2() { doTest(null, new ParameterInfoImpl[]{ new ParameterInfoImpl(-1, "z", PsiType.BOOLEAN), new ParameterInfoImpl(0, "a", PsiType.BOOLEAN), }, false); } - public void testJavadocNoNewLineInserted() throws Exception { + public void testJavadocNoNewLineInserted() { doTest(null, new ParameterInfoImpl[]{ new ParameterInfoImpl(0, "newArgs", PsiType.DOUBLE), }, false); } - public void testSuperCallFromOtherMethod() throws Exception { - doTest(null, new ParameterInfoImpl[] { + public void testSuperCallFromOtherMethod() { + doTest(null, new ParameterInfoImpl[]{ new ParameterInfoImpl(-1, "nnn", PsiType.INT, "-222"), }, false); } - public void testUseAnyVariable() throws Exception { + public void testUseAnyVariable() { doTest(null, null, null, new GenParams() { @Override public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException { - final PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); - return new ParameterInfoImpl[] { - new ParameterInfoImpl(-1, "l", factory.createTypeFromText("List", method), "null", true) + return new ParameterInfoImpl[]{ + new ParameterInfoImpl(-1, "l", myFactory.createTypeFromText("List", method), "null", true) }; } }, false); } - public void testUseThisAsAnyVariable() throws Exception { + public void testUseThisAsAnyVariable() { doTest(null, null, null, new GenParams() { @Override public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException { - final PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); - return new ParameterInfoImpl[] { - new ParameterInfoImpl(-1, "l", factory.createTypeFromText("List", method), "null", true) + return new ParameterInfoImpl[]{ + new ParameterInfoImpl(-1, "l", myFactory.createTypeFromText("List", method), "null", true) }; } }, false); } - public void testUseAnyVariableAndDefault() throws Exception { + public void testUseAnyVariableAndDefault() { doTest(null, null, null, new GenParams() { @Override public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException { - final PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); - return new ParameterInfoImpl[] { - new ParameterInfoImpl(-1, "c", factory.createTypeFromText("C", method), "null", true) + return new ParameterInfoImpl[]{ + new ParameterInfoImpl(-1, "c", myFactory.createTypeFromText("C", method), "null", true) }; } }, false); } - public void testRemoveVarargParameter() throws Exception { + public void testRemoveVarargParameter() { doTest(null, null, null, new ParameterInfoImpl[]{new ParameterInfoImpl(0)}, new ThrownExceptionInfo[0], false); } - public void testEnumConstructor() throws Exception { - doTest(null, new ParameterInfoImpl[] { + public void testEnumConstructor() { + doTest(null, new ParameterInfoImpl[]{ new ParameterInfoImpl(-1, "i", PsiType.INT, "10") }, false); } - public void testVarargs1() throws Exception { - doTest(null, new ParameterInfoImpl[] { + public void testVarargs1() { + doTest(null, new ParameterInfoImpl[]{ new ParameterInfoImpl(-1, "b", PsiType.BOOLEAN, "true"), new ParameterInfoImpl(0) }, false); } - public void testVarargs2() throws Exception { - doTest(null, new ParameterInfoImpl[] { + public void testVarargs2() { + doTest(null, new ParameterInfoImpl[]{ new ParameterInfoImpl(1, "i", PsiType.INT), new ParameterInfoImpl(0, "b", new PsiEllipsisType(PsiType.BOOLEAN)) }, false); } - public void testCovariantReturnType() throws Exception { + public void testCovariantReturnType() { doTest(CommonClassNames.JAVA_LANG_RUNNABLE, new ParameterInfoImpl[0], false); } - public void testReorderExceptions() throws Exception { + public void testReorderExceptions() { doTest(null, null, null, new SimpleParameterGen(new ParameterInfoImpl[0]), - new SimpleExceptionsGen(new ThrownExceptionInfo[]{new JavaThrownExceptionInfo(1), new JavaThrownExceptionInfo(0)}), - false); + new SimpleExceptionsGen(new ThrownExceptionInfo[]{new JavaThrownExceptionInfo(1), new JavaThrownExceptionInfo(0)}), false); } - public void testAlreadyHandled() throws Exception { + public void testAlreadyHandled() { doTest(null, null, null, new SimpleParameterGen(new ParameterInfoImpl[0]), new GenExceptions() { @Override public ThrownExceptionInfo[] genExceptions(PsiMethod method) { - return new ThrownExceptionInfo[] { - new JavaThrownExceptionInfo(-1, JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createTypeByFQClassName("java.lang.Exception", method.getResolveScope())) + return new ThrownExceptionInfo[]{ + new JavaThrownExceptionInfo(-1, myFactory.createTypeByFQClassName("java.lang.Exception", method.getResolveScope())) }; } }, - false); + false + ); } - public void testConstructorException() throws Exception { + public void testConstructorException() { doTest(null, null, null, new SimpleParameterGen(new ParameterInfoImpl[0]), new GenExceptions() { @Override public ThrownExceptionInfo[] genExceptions(PsiMethod method) { - return new ThrownExceptionInfo[] { - new JavaThrownExceptionInfo(-1, JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createTypeByFQClassName("java.io.IOException", method.getResolveScope())) + return new ThrownExceptionInfo[]{ + new JavaThrownExceptionInfo(-1, myFactory.createTypeByFQClassName("java.io.IOException", method.getResolveScope())) }; } }, - false); + false + ); } - public void testAddRuntimeException() throws Exception { + public void testAddRuntimeException() { doTest(null, null, null, new SimpleParameterGen(new ParameterInfoImpl[0]), new GenExceptions() { @Override public ThrownExceptionInfo[] genExceptions(PsiMethod method) { - return new ThrownExceptionInfo[] { - new JavaThrownExceptionInfo(-1, JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createTypeByFQClassName("java.lang.RuntimeException", method.getResolveScope())) + return new ThrownExceptionInfo[]{ + new JavaThrownExceptionInfo(-1, myFactory.createTypeByFQClassName("java.lang.RuntimeException", method.getResolveScope())) }; } }, - false); + false + ); } - public void testAddException() throws Exception { + public void testAddException() { doTest(null, null, null, new SimpleParameterGen(new ParameterInfoImpl[0]), new GenExceptions() { @Override public ThrownExceptionInfo[] genExceptions(PsiMethod method) { - return new ThrownExceptionInfo[] { - new JavaThrownExceptionInfo(-1, JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createTypeByFQClassName("java.lang.Exception", method.getResolveScope())) + return new ThrownExceptionInfo[]{ + new JavaThrownExceptionInfo(-1, myFactory.createTypeByFQClassName("java.lang.Exception", method.getResolveScope())) }; } }, - false); + false + ); } - public void testReorderWithVarargs() throws Exception { // IDEADEV-26977 - final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); - doTest(null, new ParameterInfoImpl[] { - new ParameterInfoImpl(1), - new ParameterInfoImpl(0, "s", factory.createTypeFromText("java.lang.String...", getFile())) + public void testReorderWithVarargs() { // IDEADEV-26977 + doTest(null, new ParameterInfoImpl[]{ + new ParameterInfoImpl(1), + new ParameterInfoImpl(0, "s", myFactory.createTypeFromText("java.lang.String...", getFile())) }, false); } - public void testIntroduceParameterWithDefaultValueInHierarchy() throws Exception { + public void testIntroduceParameterWithDefaultValueInHierarchy() { doTest(null, new ParameterInfoImpl[]{new ParameterInfoImpl(-1, "i", PsiType.INT, "0")}, false); } - public void testReorderMultilineMethodParameters() throws Exception { + public void testReorderMultilineMethodParameters() { // Inspired by IDEA-54902 - doTest(null, new ParameterInfoImpl[] {new ParameterInfoImpl(1), new ParameterInfoImpl(0)}, false); + doTest(null, new ParameterInfoImpl[]{new ParameterInfoImpl(1), new ParameterInfoImpl(0)}, false); } - public void testRemoveFirstParameter() throws Exception { + public void testRemoveFirstParameter() { doTest(null, new ParameterInfoImpl[]{new ParameterInfoImpl(1)}, false); } - public void testReplaceVarargWithArray() throws Exception { + public void testReplaceVarargWithArray() { doTest(null, null, null, new GenParams() { @Override public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException { - final PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); - return new ParameterInfoImpl[] { - new ParameterInfoImpl(1, "l", factory.createTypeFromText("List<T>[]", method.getParameterList()), "null", false), - new ParameterInfoImpl(0, "s", factory.createTypeFromText("String", method.getParameterList())) + return new ParameterInfoImpl[]{ + new ParameterInfoImpl(1, "l", myFactory.createTypeFromText("List<T>[]", method.getParameterList()), "null", false), + new ParameterInfoImpl(0, "s", myFactory.createTypeFromText("String", method.getParameterList())) }; } }, false); } - public void testMethodParametersAlignmentAfterMethodNameChange() throws Exception { + public void testMethodParametersAlignmentAfterMethodNameChange() { getCurrentCodeStyleSettings().ALIGN_MULTILINE_PARAMETERS = true; getCurrentCodeStyleSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; doTest(null, "test123asd", null, new SimpleParameterGen(), new SimpleExceptionsGen(), false); } - public void testMethodParametersAlignmentAfterMethodVisibilityChange() throws Exception { + public void testMethodParametersAlignmentAfterMethodVisibilityChange() { getCurrentCodeStyleSettings().ALIGN_MULTILINE_PARAMETERS = true; getCurrentCodeStyleSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; doTest(PsiModifier.PROTECTED, null, null, new SimpleParameterGen(), new SimpleExceptionsGen(), false); } - public void testMethodParametersAlignmentAfterMethodReturnTypeChange() throws Exception { + public void testMethodParametersAlignmentAfterMethodReturnTypeChange() { getCurrentCodeStyleSettings().ALIGN_MULTILINE_PARAMETERS = true; getCurrentCodeStyleSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; doTest(null, null, "Exception", new SimpleParameterGen(), new SimpleExceptionsGen(), false); } - public void testVisibilityOfOverriddenMethod() throws Exception { + public void testVisibilityOfOverriddenMethod() { doTest(PsiModifier.PACKAGE_LOCAL, "foo", "void", new ParameterInfoImpl[0], new ThrownExceptionInfo[0], false); } - public void testRemoveExceptions() throws Exception { + public void testRemoveExceptions() { doTest(null, null, "void", new SimpleParameterGen(), new SimpleExceptionsGen(), false); } - private void doTest(@Nullable String newReturnType, - ParameterInfoImpl[] parameterInfos, - final boolean generateDelegate) throws Exception { + public void testPropagateParameter() { + String basePath = "/refactoring/changeSignature/" + getTestName(false); + configureByFile(basePath + ".java"); + final PsiElement targetElement = TargetElementUtilBase.findTargetElement(getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED); + assertTrue("<caret> is not on method name", targetElement instanceof PsiMethod); + PsiMethod method = (PsiMethod)targetElement; + final PsiClass containingClass = method.getContainingClass(); + assertTrue(containingClass != null); + final PsiMethod[] callers = containingClass.findMethodsByName("caller", false); + assertTrue(callers.length > 0); + final PsiMethod caller = callers[0]; + final HashSet<PsiMethod> propagateParametersMethods = new HashSet<PsiMethod>(); + propagateParametersMethods.add(caller); + final PsiParameter[] parameters = method.getParameterList().getParameters(); + new ChangeSignatureProcessor(getProject(), method, false, null, method.getName(), + CanonicalTypes.createTypeWrapper(PsiType.VOID), new ParameterInfoImpl[]{ + new ParameterInfoImpl(0, parameters[0].getName(), parameters[0].getType()), + new ParameterInfoImpl(-1, "b", PsiType.BOOLEAN)}, null, propagateParametersMethods, null + ).run(); + checkResultByFile(basePath + "_after.java"); + } + + /* workers */ + + private void doTest(@Nullable String newReturnType, ParameterInfoImpl[] parameterInfos, boolean generateDelegate) { doTest(null, null, newReturnType, parameterInfos, new ThrownExceptionInfo[0], generateDelegate); } @@ -396,14 +424,15 @@ public class ChangeSignatureTest extends LightRefactoringTestCase { @Nullable String newReturnType, ParameterInfoImpl[] parameterInfo, ThrownExceptionInfo[] exceptionInfo, - final boolean generateDelegate) throws Exception { + boolean generateDelegate) { doTest(newVisibility, newName, newReturnType, new SimpleParameterGen(parameterInfo), new SimpleExceptionsGen(exceptionInfo), generateDelegate); } private void doTest(@PsiModifier.ModifierConstant @Nullable String newVisibility, @Nullable String newName, @Nullable @NonNls String newReturnType, - GenParams gen, final boolean generateDelegate) throws Exception { + GenParams gen, + boolean generateDelegate) { doTest(newVisibility, newName, newReturnType, gen, new SimpleExceptionsGen(), generateDelegate); } @@ -412,45 +441,17 @@ public class ChangeSignatureTest extends LightRefactoringTestCase { @Nullable String newReturnType, GenParams genParams, GenExceptions genExceptions, - final boolean generateDelegate) throws Exception { + boolean generateDelegate) { String basePath = "/refactoring/changeSignature/" + getTestName(false); - @NonNls final String filePath = basePath + ".java"; - configureByFile(filePath); - final PsiElement targetElement = TargetElementUtilBase.findTargetElement(getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED); + configureByFile(basePath + ".java"); + PsiElement targetElement = TargetElementUtilBase.findTargetElement(getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED); assertTrue("<caret> is not on method name", targetElement instanceof PsiMethod); - PsiMethod method = (PsiMethod) targetElement; - final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); - PsiType newType = newReturnType != null ? factory.createTypeFromText(newReturnType, method) : method.getReturnType(); + PsiMethod method = (PsiMethod)targetElement; + PsiType newType = newReturnType != null ? myFactory.createTypeFromText(newReturnType, method) : method.getReturnType(); new ChangeSignatureProcessor(getProject(), method, generateDelegate, newVisibility, newName != null ? newName : method.getName(), newType, genParams.genParams(method), genExceptions.genExceptions(method)).run(); - @NonNls String after = basePath + "_after.java"; - checkResultByFile(after); - } - - public void testPropagateParameter() throws Exception { - String basePath = "/refactoring/changeSignature/" + getTestName(false); - @NonNls final String filePath = basePath + ".java"; - configureByFile(filePath); - final PsiElement targetElement = TargetElementUtilBase.findTargetElement(getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED); - assertTrue("<caret> is not on method name", targetElement instanceof PsiMethod); - PsiMethod method = (PsiMethod) targetElement; - final PsiClass containingClass = method.getContainingClass(); - assertTrue(containingClass != null); - final PsiMethod[] callers = containingClass.findMethodsByName("caller", false); - assertTrue(callers.length > 0); - final PsiMethod caller = callers[0]; - final HashSet<PsiMethod> propagateParametersMethods = new HashSet<PsiMethod>(); - propagateParametersMethods.add(caller); - final PsiParameter[] parameters = method.getParameterList().getParameters(); - new ChangeSignatureProcessor(getProject(), method, false, null, - method.getName(), - CanonicalTypes.createTypeWrapper(PsiType.VOID), new ParameterInfoImpl[]{ - new ParameterInfoImpl(0, parameters[0].getName(), parameters[0].getType()), - new ParameterInfoImpl(-1, "b", PsiType.BOOLEAN)}, null, - propagateParametersMethods, null).run(); - @NonNls String after = basePath + "_after.java"; - checkResultByFile(after); + checkResultByFile(basePath + "_after.java"); } private interface GenParams { @@ -460,8 +461,7 @@ public class ChangeSignatureTest extends LightRefactoringTestCase { private static class SimpleParameterGen implements GenParams { private ParameterInfoImpl[] myInfos; - private SimpleParameterGen() { - } + private SimpleParameterGen() { } private SimpleParameterGen(ParameterInfoImpl[] infos) { myInfos = infos; diff --git a/java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java b/java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java index 2749c340c695..7521d3bd7c13 100644 --- a/java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java +++ b/java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java @@ -21,16 +21,22 @@ import com.intellij.openapi.util.DefaultJDOMExternalizer; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.JDOMExternalizable; import com.intellij.openapi.util.WriteExternalException; +import com.intellij.util.xmlb.annotations.Attribute; +import com.intellij.util.xmlb.annotations.Tag; +import com.intellij.util.xmlb.annotations.Transient; import org.jdom.Element; import java.util.regex.Matcher; import java.util.regex.Pattern; +@Tag("class-filter") public class ClassFilter implements JDOMExternalizable, Cloneable{ private static final Logger LOG = Logger.getInstance("#com.intellij.ui.classFilter.ClassFilter"); public static final ClassFilter[] EMPTY_ARRAY = new ClassFilter[0]; + @Attribute("pattern") public String PATTERN = ""; + @Attribute("enabled") public boolean ENABLED = true; private Matcher myMatcher; // to speedup matching @@ -42,9 +48,12 @@ public class ClassFilter implements JDOMExternalizable, Cloneable{ ENABLED = true; } + @Transient public String getPattern() { return PATTERN; } + + @Transient public boolean isEnabled() { return ENABLED; } diff --git a/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java b/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java index 26e0eb52d34a..d7dfea857ba9 100644 --- a/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java +++ b/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java @@ -311,26 +311,26 @@ public abstract class ExecutionWithDebuggerToolsTestCase extends ExecutionTestCa String suspendPolicy = readValue(comment, "suspendPolicy"); if (suspendPolicy != null) { - breakpoint.SUSPEND = !DebuggerSettings.SUSPEND_NONE.equals(suspendPolicy); - breakpoint.SUSPEND_POLICY = suspendPolicy; + //breakpoint.setSuspend(!DebuggerSettings.SUSPEND_NONE.equals(suspendPolicy)); + breakpoint.setSuspendPolicy(suspendPolicy); println("SUSPEND_POLICY = " + suspendPolicy, ProcessOutputTypes.SYSTEM); } String condition = readValue(comment, "Condition"); if (condition != null) { - breakpoint.CONDITION_ENABLED = true; + //breakpoint.CONDITION_ENABLED = true; breakpoint.setCondition(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, condition)); println("Condition = " + condition, ProcessOutputTypes.SYSTEM); } String passCount = readValue(comment, "Pass count"); if (passCount != null) { - breakpoint.COUNT_FILTER_ENABLED = true; - breakpoint.COUNT_FILTER = Integer.parseInt(passCount); + breakpoint.setCountFilterEnabled(true); + breakpoint.setCountFilter(Integer.parseInt(passCount)); println("Pass count = " + passCount, ProcessOutputTypes.SYSTEM); } String classFilters = readValue(comment, "Class filters"); if (classFilters != null) { - breakpoint.CLASS_FILTERS_ENABLED = true; + breakpoint.setClassFiltersEnabled(true); StringTokenizer tokenizer = new StringTokenizer(classFilters, " ,"); ArrayList<ClassFilter> lst = new ArrayList<ClassFilter>(); diff --git a/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java b/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java index f6f140049f21..5930288f2c2c 100644 --- a/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java +++ b/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,6 +39,7 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; public abstract class ModuleTestCase extends IdeaTestCase { protected final Collection<Module> myModulesToDispose = new ArrayList<Module>(); @@ -100,6 +101,7 @@ public abstract class ModuleTestCase extends IdeaTestCase { @Override public Module compute() { try { + LocalFileSystem.getInstance().refreshIoFiles(Collections.singletonList(moduleFile)); return ModuleManager.getInstance(myProject).loadModule(moduleFile.getAbsolutePath()); } catch (Exception e) { @@ -162,6 +164,7 @@ public abstract class ModuleTestCase extends IdeaTestCase { FileUtil.copyDir(dirInTestDataFile, moduleDir); final Module module = createModule(moduleDir + "/" + newModuleFileName, moduleType); final VirtualFile root = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(moduleDir); + assertNotNull(root); new WriteCommandAction.Simple(module.getProject()) { @Override protected void run() throws Throwable { |