summaryrefslogtreecommitdiff
path: root/java/java-psi-impl/src/com
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2013-09-27 10:19:19 -0700
committerTor Norbye <tnorbye@google.com>2013-09-27 10:19:28 -0700
commitf7998d05c40c24ae66d1972abfcb070552b1d7b5 (patch)
treeb0b97491f6e6591e53ea6a8f6c3a79a7dc685771 /java/java-psi-impl/src/com
parentbeca9839b2866f90da9dc517c29df2ec25a6f6a8 (diff)
downloadidea-f7998d05c40c24ae66d1972abfcb070552b1d7b5.tar.gz
Snapshot cd724ea5e27634f1c84f893f10b646937a677d56 from idea/132.425 of git://git.jetbrains.org/idea/community.git
cd724ea: Code cleanup - Idea's warnings fixed - message moved to .properties file c84855b: for performance use processNames api for java symbol contributor 334c509: IDEA-114064 Create "From Maven" library dialog doesn't handle full coords correctly (as advertised) 4e10a17: IDEA-109943 Download Library from Maven Repository: artifacts from repository with provider != maven2 are suggested, but repository is filtered off d4bc48d: IDEA-114037 Code completion should prefer variable names to unimported class names b7e5e6c: refix RUBY-11716: do not play with fire, always save and load in UTF-8 ! bb7ed8a: cleanup 15bd24e: cleanup e56b270: ProjectId, don't add project level provider if project is not mapped a0fb6a5: let IsNullCheck mean null->true, the former !null->false meaning was useless 26402542: test data fixed f800733: new inference: input/output inference variables 56d872d: NPE: find usage for db element 3ffd6a0: IDEA-114003 XDebuger breakpoint properties: strage selection jumps in breakpoint tree bbdef54: IDEA-114001 XDebuger Breakpoint Properties: enable in tree is not saved IDEA-114002 XDebuger breakpoint properties: don't close the dialog by double click IDEA-114004 XDebugger breakpoint properties: checkboxes synchronization is broken f6ff871: IDEA-114001 XDebuger Breakpoint Properties: enable in tree is not saved IDEA-114002 XDebuger breakpoint properties: don't close the dialog by double click IDEA-114004 XDebugger breakpoint properties: checkboxes synchronization is broken 8f3d962: IDEABKL-6897 Enter inserts closing brace in wrong place 6a78643: IDEABKL-6897 Enter inserts closing brace in wrong place 06b899c: IDEA-114001 XDebuger Breakpoint Properties: enable in tree is not saved IDEA-114002 XDebuger breakpoint properties: don't close the dialog by double click IDEA-114004 XDebugger breakpoint properties: checkboxes synchronization is broken aeda985: don't give focus to ant messages view f525708: new inference: overload resolution for SAM return type for implicit lambda should be ignored 6692602: cleanup current file from highlighting markup 27c6645: compilation fix 1936bb2: IDEA-107453 Compilation error if overriding methods have different access modifiers 0ddcc36: api a7f05e1: card layout fixed b007608: IDEA-110203 IDEA ignores space after comma setting for methods declaration/call [CR-IC-2022] ae02c17: hiding artifacts 90e6ed2: back to AddModuleWizard 4a029e9: Groovy: Pull-up members 6f9e810: NPE fc48bab: pull-up cbf7531: prepare pull-up refactoring for Groovy 6762d5f: cleanup b26ffb2: spaces around inner classes 41e8e70: IDEA-113333 Java formatter breaks source code: Merges statements into line comments [CR-IC-2245] ea91b55: IDEA-113815 keep "simple methods in one line" does not keep long methods [CR-IC-2486] ecd65ad: Import Eclipse code style settings from XML profile (a part of IDEA-104068) [CR-IC-2219] aacf1e4: IDEA-113844 (handling of core component initialization failures when spoiled by plugins) 8dc3ede: IDEA-112387 Reformat code with rearrange entires on = fail on enum [CR-IC-2205] 72ddb9e: Merge remote-tracking branch 'origin/master' 209340b: Add the description for MavenDuplicatePluginInspection. de367e1: Merge branch 'svn1_8_new' 1a70497: IdeaTestAssistant: fix test data d6a2510: svn: Fixed "Import" when path/url contains '@' symbol 94c4223: svn: Implemented "Export" action for command line 8913712: parameter popup: escape for annotation methods (IDEA-113971) fdf7312: svn: Made event handler for checkout/export utilize passed progress indicator (instead of just current thread progress indicator) f653713: IDEA-105758: Contradiction between error and fix actions (Java EE artifact) eac456f: Platform: ability to provide native icons for PsiElements (PsiFile/Directory) AppCode: blue icons for folders 4d5c47a: IDEA-77519: Project fails to open when workspace.xml is empty c40e732: two classes temporary restored to fix backward compatibility b6b3bc6: added optional dependencies for framework support providers a9dae78: IDEA-90661: recognize IBM JDK jars 6b44958: cleanup & javadoc 0c0a6a6: IDEA-108785 Allow applying the same context to many selected live templates 247661b: don't search for unknown path macros in the middle of xml unless asked so by PathMacroFilter (IDEA-102674) 90222d5: hopefully fix control flow building stack inconsistency assertions in case when a PCE is thrown 241e44b: EA-50288 - CCE: RefJavaUtilImpl.getTopLevelClass 22d5c2f: ensure to filter already inserted annotations (IDEA-113785) 27b76b4: inplace introducer: another case to restore expression (IDEA-113352) 603e138: add mnemonics (IDEA-113889) a8c374c: XSuspendPolicyPanel "Make default" (requires for new JavaBreakpointType) remove unused methods 4f19472: CR-IC-2485 (deprecation policy specified; deprecated API usage upgraded) 7231807: JavaBreakpointType isSuspendThreadSupported true 8637e89: register JavaBreakpointType, but hide under system property java.debugger.xBreakpoint 0b2d5f0: cleanup 5cc1f5e: EA-50289 (CCE: TooBroadScopeInspection$TooBroadScopeInspectionFix.getCommentText) 505b86e: new inference: pertinent to applicability 8ac21fd: cleanup 2c5f39e: cleanup f6efaa9: simplify DebuggerInvocationUtil bf8865f: overrides 0d49e5b: JavaBreakpointType canPutAt 33ebea3: extract XLineBreakpointTypeBase de7d963: extract XDebuggerEditorsProviderBase, init JavaBreakpointType (is not registered, so, not in action now) ed777e6: remove deprecated canPutAt 9163435: overrides 44af67f8: extract XDebuggerUtil.getInstance().getGroupingByFileRuleAsList() b93b27c: add missing Overrides 0857036: cleanup ae791a7: new inference: test preparations 48120ab: IdeaTestAssistant: add resolving and completion inside TestDataPath annotation 971544b: remove empty unused class c5642d9: hippie completion: split complex tokens by spaces e1383b1: refix and add test for IDEA-90294 Don't use substring match in word completion fbae94c: EA-49809 Made client factories final in SvnVcs 2b4b70f: Fix OC-8127: Appcode hangs on reformatting (endless right shift) +review CR-OC @Anton.Makeev, @Rustam.Vishnyakov b7314cf: fix pycharm detection 5f0bb3c: revert error checking 5f99590: svn: Implemented "Import" action for command line ad04905: svn: Changed import logic to use common commit event handler (instead of checkout event handler) 1a45be0: custom options 8d278a3: MavenArchetypesPanel extracted 32eeb4c: aggregation panel invisible 9388cc4: new project wizard: project type sorting 2c02a07: svn: Add "Skipped" event processing in commit/import output for command line d365580: svn: Refactored commit output parsing for command line b1cc312: immutable dfa offset stack 5c494fb: toolbarIcon is nullable 4304880: dfa: traverse only flushable variables, not all ed08eab: immutable EqClass 03de519: overrides f8661d9: return empty collection if list of storage files is empty 81a998c: IDEA-111030: Add Framework Support: Ok is disabled for the only selected Web Application 4ce1cc8: unused class removed 84f7401: svn: Added final status bar message for Import ("Committed revision xxx") aa1d479: library editor: 'attach javadoc' extracted to separate button so the main '+' button won't show popup 1612198: cleanup e180456: cleanup 546fffe: Merge remote-tracking branch 'origin/master' c3caf6c: Merge remote-tracking branch 'origin/master' 5cd2b37: assertion for EA-45385 - NPE: XmlTagImpl.getDescriptor 99563ea: EA-49418 - NPE: InjectLanguageAction.invokeImpl dc82859: cleanup f70ef96: EA-50139 - assert: TextRange.<init> 990e410: svn: Removed unused code (from "Ignore" functionality) 6604613: svn: Implemented "Ignore" functionality on subversion level d544d03: cleanup after notnullification 5330d9e: plugin suggester: suggest plugins from repository by unknown facet 1ccf92a: error which should never happen replaced by assertion 889d3ce: improved dialog for choosing root types of added roots 0eb34fa: hide "use out of process build" option from UI d79e13e: plugin suggester: suggest plugins from repository by unknown facet 00a127b: Use shell options only if applicable. b4f21b9: Don't fail to create SSH terminal session if we failed to create local terminal session. 8e5cb57: test for "Unnecessary unicode escape sequence" inspection dc8acce: temp revert c7c4431: fix SliceBackwardTest 3e16a04: svn: Implemented "Edit Revision Comment" action for command line c54948a: 'async' added e4f7950: svn: Correctly create externals that have '@' in url - add '@' at url end 9b66e1c: svn: Fix line separators duplication for "Create External" action for SVNKit a98dc14: svn: Implemented "Create External" action for command line 32e30d1: EA-50206 - assert: FileManagerImpl.findFile 4a4c0cc: svn: Unify line separator for multiline properties 4b9422b: Reverted: Semantic highlighting level to avoid conflicts with "unused symbol" annotations [CR-IC-2435] ad970ef: lambda: propagate wildcards elimination e78ab51: lambda: check formal params for equality, eliminate wildcards during inference according to 15.27.3 fc9a196: new inference: ignore proper types in mutual eq constraints generation 7bc0048: new inference: void compatible according to return values 939fc45: prepare for test new inference eef6eb2: new inference: exact method reference 172daec: new inference: eliminate delayed constrains according to 0.6.3 ec93384: postpone type evaluation e689d68: new inference: make use of ex constraint 7838f8e: Merge branch 'safe-sudo-escaping' 1c22df9: Add grails-app/resources as resources folder, not a source folder. a7f094d: fix NPE e1fe819: Added ExecUtil.sudoAndGetOutput() with safe escaping and quoting for Mac and Linux 6bf3a02: fixed EA-48905 - SIOOBE: ParameterInfoComponent$OneLineComponent.buildLabelText c853c69: system dependent paths in groovy shell db7d97f: Merge remote-tracking branch 'origin/master' 65426f9: mark as DumbAware 0d1a074: Support active links in GotIt panel c7297a0: debugging blinking test 755c6b2: IDEA-113938 "Submit feedback" should pre-fill project and affected version ff45141: dfa: don't go into the same instruction twice with the same state 3361944: a bit more parsimonous DfaMemoryStateImpl.createCopy 028d28b: dfa states should not change while in queue => no need to copy them 1709382: dfa: use UnorderedPair instead of two-element set e8dbc21: immutable DfaVariableState, for faster copying and less memory usage 666ed52: IDEA-70241 (Replace with '{@code}' inspection doesn't replace all occurrences in file.) 71bd9cf: Merge remote-tracking branch 'origin/master' c923098: EA-47881 - IOE: GroovyPsiElementFactoryImpl.createGroovyFileChecked 8b97940: cleanup logging 6e4b81e: EA-50137 - assert: TestObject.addClassesListToJavaParameters 5381d51: cleanup dc2d1b2: notnull f419fab: "todo" moved out of lang-impl 97cd633: attributes cleanup 75b3eaa: notnull c7fa9af: cleanup f5b5bf4: cleanup 776b16b: cleanup bf3cea4: made fields final 87913f7: cleanup 798e94e: cleanup, get rid of buggy duplicate node renderer 50f13e4: removed deprecated methods from ExternalAnnotator 6d9c887: avoid deprecated methods 4852116: minor 9cd549c: now Searchable. fixes test. 302302a: typo 26d8885: - handle strings with more than one quote used for start / end delimiters - proper retrieving syntax highlighter in case of non languge based syntaxhighlighter (quite often it is bound to file type) - Find: String literals only: Throwable at StringSearcher.scan() on XML with a string (IDEA-113885) - fix for backward search not ending when whole word option used 4dfd0c7: Encapsulate field dialog: explicit value for "Use accessors when field is accessible" when "as is" visibility is selected e1aff45: typo :((( 6237b9b: test fixed 6c0d31b: test fixed 493cfae: update test data 711bca1: update test data f1bc615: update test data 8dd18de: update test data e61a901: update test data 0be96e9: update test data aac178b: dfa: remove queued state duplication 6a25f5d: dfa: don't reschedule already processed states, cleanup 7559dfc: Semantic highlighting level to avoid conflicts with "unused symbol" annotations [CR-IC-2435], for WI-19396, WI-20126 (cherry picked from commit 56d66dc) 7c27aef: extract collectUsedJars() function 12f59ff: update test data 03df890: update test data 1efd604: update test data 2c1726e: update test data 24bf1d1: Merge remote-tracking branch 'origin/master' 8f26a8b: improved duplicates search in python extract method 9bfcbbe: setup resource roots when project is imported from Maven (IDEA-57398) 64594cd: diagnostics for EA-49831 0d76c32: add support for frameworks step: sorting restored b510334: IDEA-113294 indentation of brace in a lambda expression corrected [CR-IC-2426] 9651be4: IDEA-113910 Gradle: code insight; dependencies DSL resolving 25595c8: new inference: checked exceptions compatibility constraint 6b8f295: dump highlighting test data without markup 636719b: now that we have dfa state hashing, use it instead of linear lookup 3813120: dfa: don't merge states when there's only one 3fd9ba8: IDEA-113910 Gradle: code insight; dependencies DSL resolving 57a6aeb: IDEA-113910 Gradle: code insight; dependencies resolving da23b6c: Merge remote-tracking branch 'origin/master' 7ca6ea3: Merge remote branch 'origin/master' cdc6d6a: show deprecated make implementation warning once on first compilation after project opening 090c4e3: dfa state merging: cache copies e6ee024: Allows getting Gradle home without having a Project. 0391639: Gradle VM Options are now saved in between sessions. f5412f0: resource root: show 'New Directory' action instead of 'New Package' under resource roots 1637f6b: notnullification 87f394f: IDEA-113904 (Add New Module from Project Structure dialog wants to create new project) a7c75f6: IDEA-113865 ('Equals should check class of parameter' shouldn't warn on identity equals) 2486e9e: dfa: merge several states to account for variables with several possible values 4d4f4b0: dfa: some minor things and caching c14961f: UnorderedPair in platform 5ad442d: Merge remote-tracking branch 'origin/master' 946a281: Scroll to bottom on typing in terminal (PY-10344). e5a0548: Close all connections on dispose. f61f6a2: changes from tech-writers b82b0bb: dfa: state merging interruptibility 3893373: VcsDirtyScopeManagerImpl: log who marks everything dirty 41e5381: Merge remote-tracking branch 'origin/master' da21efb: JediTerm updated. beb1d1a: Merge remote-tracking branch 'origin/master' ed3a2b5: skip the whole document if some component has disabled roaming type (details CR-IU-308) d66309b: Fix antialiasing. e55fae1: dfa: abstract out eq class into EqClass class 370d44d: dfa: remove trivial state facts that constant != another constant 4ccfcf7: UsagesStatistic must specify roaming disabled 75894ae: cleanup 784b4e3: DimensionService: cleanup, order of stored data should be stable 36443b6: overrides b70b1dc: overrides dfe38fb: simplify some constant conditions and greenify 9a08478: IDEA-85961 (Pattern BACKSLASH_PATTERN = Pattern.compile("\\", Pattern.LITERAL) is always marked red.) d0bdc3b: simplify load from providers – we don't need to filter again (our save do it, in any case it is absurd to store component with global roaming in the project level file, — should be refine later) bf85e1b: cleanup 9c30823: remove unused methods f671c09: overrides 3bd62bc: ComponentRoamingManager should not keep defaults (we use RoamingType.PER_USER by default) a8f1063: CR-IU-300 remove outdated EP ComponentRoamingType b182751: CR-IU-300 remove outdated RoamingTypePerPlatform 994389c: another java.util.regex.Pattern.compile() parameter annotation 301710d: IDEA-113866 (this. not suggested for fields of anonymous inner classes) f5d03c4: dfa: don't consider final getters same as immutable fields 272a6d0: Corresponding parents for console colors. 71298ce: Bright console colors for Monokai. f39c34b: Console colors for WarmNeon scheme. 7548e47: Black is invisible on dark background (in RegExps for example). ca6b784: Change bloody red to light pink for numbers (pink is specific to Neon color schemes while red is not, also eyes say thanks). 7f627d9: Console colors for Twilight scheme fixed. a5eb2fc: Console colors for Monokai scheme fixed. f7da145: DfaPsiType: add @NotNull b216102: rebomb test b349547: diagnostics for inconsistencies during control flow building 6823425: dfa: only perform costly state merging when it has chances - after jumps fea8871: dfa: fighting too complex methods; join complementary memory states after fork to avoid having too many states 0ac2084: DfaMemoryStateImpl: introduce unwrap; compare variable values with their non-initialized counterparts e919b8b: dfa: only goto catch on non-trivial method calls and throws e2ea04f: new inference: initial method reference constraint a9dde36: new inference: check substituted descriptor return type 3e5b164: new inference: expression inside condition should be poly, target type for conditional expression ff9f2e9: new inference: emulate fresh variable - do not override vars with captured ones f415702: new inference: default constructor as poly expression argument ee56497: new inference: symmetric variable bounds 4a46b24: new inference: init inter call inference 06829c5: Merge remote-tracking branch 'origin/master' e3f213f: Console colors for Darcula. f748505: IDEA-57940 Cyclic expand word should take into account all open files 460ef47: StreamProvider.isVersioningRequired 8029f47: Bright yellow made more visible on white background. 96006be: Default console colors as in xterm palette, gray and dark gray from standard vga palette for better readability. a378414: Bight console colors added to settings. 54e6582: builder-based project types b0b2cf8: template-based project types? e741484: CPU hogging fix again eb22a99: fix todo duplication when several pattern match -> prefer finding match with last pattern (in settings list), thus default TODO pattern is matched last a4d4371: fix compilation 2f823ba: Difference Groovy Shell & Groovy Console actions 3e876f4: IDEA-113590 annotations as annotation values 732cafd: dead code a712f87: pull up 'isQualified()' method 4edd102: extract base class from PullUpDialog 10d89d6: remove obsolete test a0750e4: delete envFile manually 114cbb2: IDEA-113861 Gradle: it could be possible to hide 'Gradle: download' progress to the background ca416b8: 'More' element for classes, files, action, and settings. Better renderer. b2a550c: test framework: drop temp directory on light project close 8aaf53b: greenify ActionsTreeUtil a bit 922d41a: layout 2cd7326: adding frameworks support 2bd8fb0: cleanup 4ea6442: ProjectSummaryStep 9fdcdcd: commit project name bd39918: new project wizard: first test 630fc14: External system: use URLs in compile output paths 85dbe5f: IDEA-65114 "Add Maven projects" cannot be undone 5041ae5: test framework: returning of the data provider 16e2072: @Nullable XBreakpoint.getProperties reverted +review CR-IC-2418 df4da38: dump shell environment to a temporary file to reduce probability of malformed lines occurrence 280d52a: let event log warning color be orange (IDEA-113802) a30b2ae: IDEA-113836 Console folding: add TestNG related patterns cbeb0f1: don't change mouse cursor during goto name population (IDEA-113800) fb5ad5b: IDEA-113638 ChooseByName restart on write action spawns a new thread 89b3767: disable autopopup in groovy shell if selection by chars is enabled (IDEA-112820) 9fa36be: CompletionConfidence: don't force API users to implement unused method 34cf7eb: Console Folding: proper capitalization 5e8aa44: IDEA-113855 Search Everywhere looks scrambled at first start 71723cb: svn: Refactored executable validation - use separate version client 1114cfe: javadoc 0738800: jps model: simplification, source roots always have default properties b1d5062: jps model: JpsElementType converted to interface to allow reusing common base class 229deb0: test framework: ok, put light project file into ephemeral directory, but keep it for a project's life 6e8b950: ensure "thread" suspend policy for logging breakpoints d67c04e: EA-49809 Move client factories creation to SvnVcs constructor (instead of active() method) 935cdba: new inference: initial tests 970a180: encapsulate read access to USE_COMPILE_SERVER option b9b3fc8: remote agents - extract to remote servers cfe8e2b: WEB-9335 Bad insert pair brace in CSS 2815c22: WEB-9334 Incremental selection works bad with negative CSS values d023471: new "Unnecessary unicode escape sequence" inspection 945b069: unicode escape needs at least one 'u' 8e7797b: chrome still crashed, revert to old, not-recursive speed search 1917d86: Merge remote-tracking branch 'origin/master' c18e6bd: Lense mode "internal" preview db88427: Merge branch 'svn1_8_new' 7c64e8b: test framework: do not put light project file into ephemeral directory af09e11: remove @Nullable from key.get as it's too generic d49df32: svn: Refactored prompting for working copy format - make return not null format d6086ae: dfa: types with wildcard parameters are not equal 3d28aa5: Optimization: check exiting of griffon-app first b016c04: correct ephemeral state copy (IDEA-113143 Calling method with contract shouldn't result in nullability suspicion) 189573f: svn: Refactored upgrade working copy format dialog - use list of available formats (instead of separate fields for each format) 60c471b: Rename test 1a42f59: Remove using of unnecessary StringBuilder a56db90: Use MultiMap 340cf22: Calling method with contract shouldn't result in nullability suspicion (IDEA-113763, IDEA-113699, almost IDEA-113143) f2a563b: dfa: unify nullability violation processing 709af86: dfa: expand contract test 1cddfb4: dfa cleanup: skipping reports on method calls is now done via unknown variable mechanism 2765dab: dfa: spare some minor cpu cycles 8bc7465: svn: Added "1.8" option to upgrade/checkout dialogs c266bd2: IDEA-66603 Maven3: provide inspection that checks duplicate declarations of plugins af32923: SpellChecker: "cyclomatic" 5f4f98f: svn: Refactored working copy format selection dialog to use WorkingCopyFormat instances instead of just strings e33b58b: MismatchedCollectionQueryUpdateInspection -- added "compute" prefix (from j.u.Map in JDK8) 7d54b2e: new inference: accept nonProper eq bounds 457d95b: new inference: distinguish different captures 5b5f52e: new inference: assertions caused by raw types 3848de4: new inference: open top level captured wildcards 35d59c0: new inference: extend usage of already inferred variables 4f7b572: new inference: inference of calls in arguments during outer call inference bfa7879: new inference: captured variables from outer calls to be included ed95269: new inference: eq bound for S<=T constraint reduction 12a0faf: better positioning 13029b7: different position layout algorithms 39e6e21: EA-49923 - Fixed working copy format detection for default project d521e9d: JDK combobox should show JDK home 17fe05e: Fix typo 7ab769b: IDEA-16077 Maven embedder runs in the 'wrong' JDK add "embedder JDK" option 418ddc0: Inline string constant 6a8f1e2: IDEA-16077 Maven embedder runs in the 'wrong' JDK extract MavenJdkCombobox 46078c4: svn: Refactored detection if command line implementation should be used (use utility method) 24106fc: XDebugger: @Nullable XBreakpoint.getProperties() 3dc6f07: extract util method 476dac4: Reinit checkbox state on create 39cf1fd: Structure viewer for simple editors support fixed a38a251: Show filters only for table editor + a few model and UI fixes cbd5630: Initial dynamic filters model + columns header improved 281c008: svn: Support nullable SVNStatusClient in status implementation for SVNKit 1840d42: simplification fbcba0f: svn: Make command line clients (info, status) use vcs instead of project instances ae8b41b: Merge remote-tracking branch 'origin/master' a97397c: Extract method. 3b9eca4: new project wizard: preparing test infrastructure 327ddb0: Lense mode "internal" preview 0ede5e1: new project wizard: AbstractProjectWizard extracted a94b556: IDEA-111335 Gradle: task tree is incorrectly displayed if tasks are added to sub-projects via 'subprojects' method bfd366f: Merge remote-tracking branch 'origin/master' 0ef2a82: calls to obsolete method removed from build scripts 2df016f: AntLoggerFactory inner class made static to fix NoSuchMethodException in Logger.setFactory fe876e2: svn: Clients for update command renamed and moved to corresponding package a38d90e: Terminal color settings. bd285b8: svn: Refactored update logic to common ClientFactory model 9cc13da: platform: ignore hidden Windows files d87664c: test framework: relic property dropped 5f6ef06: svn: Removed unused "common ancestor" behavior from command line update client 3667fe1: Find in strings with reg exp with start / end match markers doesn't work without string delimiters (IDEA-113788) 94a079f: svn: Refactored "update" command - explicitly create new SVNKit update client for each update/switch operation 0344e91: new project wizard: added option to use framework libraries from an app server 2882ac0: svn: Removed unused methods from "update" client 17ea275: svn: Removed unused SvnProxies class c926181: WEB-9342 External Tool fails on OSX if an executable file basename specified a3433f9: svn: Removed unused methods from "info" client ec3112d: Optimize SassExtensionFunctionsIndex 9f1abf7: nosplash shouldn't prevent from plugin update 4c7154d: dfa: use cached nullability b81e9c3: dfa: less frequent "too long" check 0b0eba9: DfaValueFactory: use List instead of TIntObjectHashMap for sequential keys 95d5433: introduce DfaPsiType without nullability, to quickly check assignability/convertibility in DfaVariableState b901d90: IDEA-96713 Incorrect options shown for 'implements' e02e2c4: IDEA-113780 "Annotate" from history fixed for renamed/moved files fe00f73: test framework: stability improvements 76d664d: platform: suspicious event logging b204bdf: Cleanup (de-duplication) 7ba9ff0: spelling ece939c: make public for Upsource 496db4d: xdebugger: rebuild standalone variables view on EDT eae27cb: xdebugger: supported rebuilding of standalone variables view 8bf5204: xdebugger api: added convenient method 43dbb6f: Terminal options. 3db1f5c: Blink period and antialiasing settings. 88264bd: IDEA-108147 Use "merge sources" wrapper object instead of just string representation as data model for "Merge Sources" column (to correctly get file revision object and show details panel) 111e6ba: IDEA-108147 While building history for element make check "if element parent or child was changed in given revision" only be performed for non-"merge source" revisions e07828d: svn: Implemented support for "merged revisions" parsing in history logic for command line 1586c4a: svn: history logic refactored for command line - get and parse history data in xml format 0ac1dd2: IDEA-94942 Refactored "Annotate" implementation for command line - use utility method for parsing ba1e5e0: IDEA-94942 Implemented merge history support for "Annotate" action 4c3b0a8: IDEA-94942 Implemented "Switch" logic (during update) Change-Id: I7092ae66ff47d353a5b9770d1d91f77369bb7734
Diffstat (limited to 'java/java-psi-impl/src/com')
-rw-r--r--java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaDocLexer.java3
-rw-r--r--java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaLexer.java3
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java10
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java92
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java169
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java3
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariablesOrder.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java6
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java164
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ConstraintFormula.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java95
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/InputOutputConstraintFormula.java112
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java36
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java100
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/SubtypingConstraint.java23
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeCompatibilityConstraint.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerExpressionImpl.java29
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java5
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java68
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java9
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java36
24 files changed, 851 insertions, 124 deletions
diff --git a/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaDocLexer.java b/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaDocLexer.java
index de1e03f30d6d..0592f9e916d8 100644
--- a/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaDocLexer.java
+++ b/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaDocLexer.java
@@ -54,7 +54,7 @@ public class JavaDocLexer extends MergingLexerAdapter {
}
@Override
- public final void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public final void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
myBuffer = buffer;
myBufferIndex = startOffset;
myBufferEndOffset = endOffset;
@@ -68,6 +68,7 @@ public class JavaDocLexer extends MergingLexerAdapter {
return myState;
}
+ @NotNull
@Override
public CharSequence getBufferSequence() {
return myBuffer;
diff --git a/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaLexer.java b/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaLexer.java
index db6e5e21aa25..f1c6c19453bb 100644
--- a/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaLexer.java
+++ b/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaLexer.java
@@ -175,7 +175,7 @@ public class JavaLexer extends LexerBase {
}
@Override
- public final void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public final void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
myBuffer = buffer;
myBufferArray = CharArrayUtil.fromSequenceWithoutCopying(buffer);
myBufferIndex = startOffset;
@@ -417,6 +417,7 @@ public class JavaLexer extends LexerBase {
return pos;
}
+ @NotNull
@Override
public CharSequence getBufferSequence() {
return myBuffer;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java
index bc62cc802fad..103b828b1873 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java
@@ -799,7 +799,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
@Override
public void processVariants(@NotNull final PsiScopeProcessor processor) {
final OrFilter filter = new OrFilter();
- if (isInCode() && !(getParent() instanceof PsiImportStatement)) {
+ if (isInCode() && !(getParent() instanceof PsiImportStatement) && !(getParent() instanceof PsiReferenceList)) {
filter.addFilter(new AndFilter(ElementClassFilter.METHOD, new NotFilter(new ConstructorFilter())));
filter.addFilter(ElementClassFilter.VARIABLE);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
index 68bb8b865c92..15aba8821ffe 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.impl.source.resolve;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.pom.java.LanguageLevel;
@@ -196,7 +197,16 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
.getSubstitutionForTypeParameter(typeParam, param, arg, isContraVariantPosition, languageLevel);
}
+ private PsiInferenceHelper myTestHelper;
+
+ public void setTestHelper(PsiInferenceHelper testHelper) {
+ myTestHelper = testHelper;
+ }
+
public PsiInferenceHelper getInferenceHelper(LanguageLevel languageLevel) {
+ if (ApplicationManager.getApplication().isUnitTestMode()) {
+ return myTestHelper != null ? myTestHelper : new PsiOldInferenceHelper(myManager);
+ }
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && Registry.is("enable.graph.inference", false)) {
return new PsiGraphInferenceHelper(myManager);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java
new file mode 100644
index 000000000000..4806a51a5dcf
--- /dev/null
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.impl.source.resolve.graphInference;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.graphInference.constraints.TypeEqualityConstraint;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class FunctionalInterfaceParameterizationUtil {
+ private static final Logger LOG = Logger.getInstance("#" + FunctionalInterfaceParameterizationUtil.class.getName());
+
+ public static boolean isWildcardParameterized(@Nullable PsiType classType) {
+ if (classType == null) return false;
+ if (classType instanceof PsiIntersectionType) {
+ for (PsiType type : ((PsiIntersectionType)classType).getConjuncts()) {
+ if (!isWildcardParameterized(type)) return false;
+ }
+ }
+ if (classType instanceof PsiClassType) {
+ for (PsiType type : ((PsiClassType)classType).getParameters()) {
+ if (type instanceof PsiWildcardType || type instanceof PsiCapturedWildcardType) {
+ return true;
+ }
+ }
+ return false;
+ }
+ LOG.error("Unexpected type: " + classType);
+ return false;
+ }
+
+ @Nullable
+ public static PsiType getFunctionalType(@Nullable PsiType psiClassType, PsiLambdaExpression expr) {
+ if (!expr.hasFormalParameterTypes() || expr.getParameterList().getParametersCount() == 0) return psiClassType;
+ if (!isWildcardParameterized(psiClassType)) {
+ return psiClassType;
+ }
+ final PsiParameter[] lambdaParams = expr.getParameterList().getParameters();
+ if (psiClassType instanceof PsiIntersectionType) {
+ for (PsiType psiType : ((PsiIntersectionType)psiClassType).getConjuncts()) {
+ final PsiType functionalType = getFunctionalType(psiType, expr);
+ if (functionalType != null) return functionalType;
+ }
+ return null;
+ }
+
+ LOG.assertTrue(psiClassType instanceof PsiClassType, "Unexpected type: " + psiClassType);
+ final PsiType[] parameters = ((PsiClassType)psiClassType).getParameters();
+ final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)psiClassType).resolveGenerics();
+ PsiClass psiClass = resolveResult.getElement();
+
+ if (psiClass != null) {
+
+ final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
+ if (interfaceMethod == null) return null;
+
+ final InferenceSession session = new InferenceSession(PsiSubstitutor.EMPTY);
+ PsiTypeParameter[] typeParameters = psiClass.getTypeParameters();
+ if (typeParameters.length != parameters.length) {
+ return null;
+ }
+
+ for (int i = 0; i < typeParameters.length; i++) {
+ session.addVariable(typeParameters[i], parameters[i]);
+ }
+
+ final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(psiClass.getProject());
+ final PsiParameter[] targetMethodParams = interfaceMethod.getParameterList().getParameters();
+ for (int i = 0; i < targetMethodParams.length; i++) {
+ session.addConstraint(new TypeEqualityConstraint(lambdaParams[i].getType(), targetMethodParams[i].getType()));
+ }
+
+ final PsiClassType parameterization = elementFactory.createType(psiClass, session.infer());
+ if (!isWildcardParameterized(parameterization)) return parameterization;
+ }
+ return null;
+ }
+}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java
index a63e43824986..e1c3d63d8b15 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java
@@ -174,8 +174,10 @@ public class InferenceIncorporationPhase {
private void eqEq(List<PsiType> eqBounds) {
for (int i = 0; i < eqBounds.size(); i++) {
PsiType sBound= eqBounds.get(i);
+ if (sBound == null) continue;
for (int j = i + 1; j < eqBounds.size(); j++) {
final PsiType tBound = eqBounds.get(j);
+ if (tBound == null) continue;
addConstraint(new TypeEqualityConstraint(tBound, sBound));
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java
index dba4a7289a5e..df785073a6d7 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java
@@ -18,13 +18,17 @@ package com.intellij.psi.impl.source.resolve.graphInference;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
+import com.intellij.psi.impl.PsiImplUtil;
+import com.intellij.psi.impl.source.resolve.graphInference.constraints.CheckedExceptionCompatibilityConstraint;
import com.intellij.psi.impl.source.resolve.graphInference.constraints.ConstraintFormula;
import com.intellij.psi.impl.source.resolve.graphInference.constraints.ExpressionCompatibilityConstraint;
import com.intellij.psi.impl.source.resolve.graphInference.constraints.TypeCompatibilityConstraint;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.util.ArrayUtilRt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,7 +42,6 @@ public class InferenceSession {
private Map<PsiTypeParameter, InferenceVariable> myInferenceVariables = new LinkedHashMap<PsiTypeParameter, InferenceVariable>();
private final List<ConstraintFormula> myConstraints = new ArrayList<ConstraintFormula>();
- private final List<ConstraintFormula> myDelayedConstraints = new ArrayList<ConstraintFormula>();
private PsiSubstitutor mySiteSubstitutor;
private PsiManager myManager;
@@ -46,6 +49,10 @@ public class InferenceSession {
private final InferenceIncorporationPhase myIncorporationPhase = new InferenceIncorporationPhase(this);
+ public InferenceSession(PsiSubstitutor siteSubstitutor) {
+ mySiteSubstitutor = siteSubstitutor;
+ }
+
public InferenceSession(PsiTypeParameter[] typeParams,
PsiType[] leftTypes,
PsiType[] rightTypes,
@@ -75,14 +82,10 @@ public class InferenceSession {
if (parameters.length > 0) {
for (int i = 0; i < args.length; i++) {
- PsiType parameterType = mySiteSubstitutor.substitute(parameters[i < parameters.length ? i : parameters.length - 1].getType());
- if (parameterType instanceof PsiEllipsisType) {
- if (args.length != parameters.length || args[i] != null && !(args[i].getType() instanceof PsiArrayType)) {
- parameterType = ((PsiEllipsisType)parameterType).getComponentType();
- }
- }
+ PsiType parameterType = getParameterType(parameters, args, i, mySiteSubstitutor);
if (args[i] != null) {
myConstraints.add(new ExpressionCompatibilityConstraint(args[i], parameterType));
+ //myConstraints.add(new CheckedExceptionCompatibilityConstraint(args[i], parameterType));
}
}
}
@@ -98,11 +101,66 @@ public class InferenceSession {
}
}
+ public static boolean isPertinentToApplicability(PsiExpression expr, PsiMethod method) {
+ if (expr instanceof PsiLambdaExpression) {
+ if (((PsiLambdaExpression)expr).hasFormalParameterTypes()) return true;
+ for (PsiExpression expression : LambdaUtil.getReturnExpressions((PsiLambdaExpression)expr)) {
+ if (!isPertinentToApplicability(expression, method)) return false;
+ }
+ if (method.getTypeParameters().length > 0) {
+ final PsiElement parent = PsiUtil.skipParenthesizedExprUp(expr.getParent());
+ if (parent instanceof PsiExpressionList) {
+ final PsiElement gParent = parent.getParent();
+ if (gParent instanceof PsiCallExpression && ((PsiCallExpression)gParent).getTypeArgumentList().getTypeParameterElements().length == 0) {
+ final int idx = LambdaUtil.getLambdaIdx(((PsiExpressionList)parent), expr);
+ final PsiParameter[] parameters = method.getParameterList().getParameters();
+ PsiType paramType;
+ if (idx > parameters.length - 1) {
+ final PsiType lastParamType = parameters[parameters.length - 1].getType();
+ paramType = parameters[parameters.length - 1].isVarArgs() ? ((PsiEllipsisType)lastParamType).getComponentType() : lastParamType;
+ }
+ else {
+ paramType = parameters[idx].getType();
+ }
+ final PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(paramType);
+ if (psiClass instanceof PsiTypeParameter && ((PsiTypeParameter)psiClass).getOwner() == method) return false;
+ }
+ }
+ }
+ return true;
+ }
+ if (expr instanceof PsiMethodReferenceExpression) {
+ return ((PsiMethodReferenceExpression)expr).isExact();
+ }
+ if (expr instanceof PsiParenthesizedExpression) {
+ return isPertinentToApplicability(((PsiParenthesizedExpression)expr).getExpression(), method);
+ }
+ if (expr instanceof PsiConditionalExpression) {
+ final PsiExpression thenExpression = ((PsiConditionalExpression)expr).getThenExpression();
+ if (!isPertinentToApplicability(thenExpression, method)) return false;
+ final PsiExpression elseExpression = ((PsiConditionalExpression)expr).getElseExpression();
+ if (!isPertinentToApplicability(elseExpression, method)) return false;
+ }
+ return true;
+ }
+
+ private static PsiType getParameterType(PsiParameter[] parameters, PsiExpression[] args, int i, PsiSubstitutor substitutor) {
+ PsiType parameterType = substitutor.substitute(parameters[i < parameters.length ? i : parameters.length - 1].getType());
+ if (parameterType instanceof PsiEllipsisType) {
+ if (args.length != parameters.length || PsiPolyExpressionUtil
+ .isPolyExpression(args[i]) || args[i] != null && !(args[i].getType() instanceof PsiArrayType)) {
+ parameterType = ((PsiEllipsisType)parameterType).getComponentType();
+ }
+ }
+ return parameterType;
+ }
+
@NotNull
public PsiSubstitutor infer() {
repeatInferencePhases();
for (InferenceVariable inferenceVariable : myInferenceVariables.values()) {
+ if (inferenceVariable.isCaptured()) continue;
final PsiTypeParameter typeParameter = inferenceVariable.getParameter();
PsiType instantiation = inferenceVariable.getInstantiation();
if (instantiation == PsiType.NULL) {
@@ -136,25 +194,60 @@ public class InferenceSession {
}
}
}
+
+ public void addCapturedVariable(PsiTypeParameter param) {
+ if (myInferenceVariables.containsKey(param)) return; //same method call
+ final InferenceVariable variable = new InferenceVariable(param);
+ variable.setCaptured(true);
+ myInferenceVariables.put(param, variable);
+ }
private void initReturnTypeConstraint(PsiMethod method, PsiCallExpression context) {
if (PsiPolyExpressionUtil.isPolyExpression(context) ||
context instanceof PsiNewExpression && PsiDiamondType.ourDiamondGuard.currentStack().contains(context)) {
final PsiType returnType = method.getReturnType();
if (!PsiType.VOID.equals(returnType) && returnType != null) {
- final PsiType targetType = PsiPolyExpressionUtil.getTargetType(context);//todo primitive type
+ PsiType targetType = PsiTypesUtil.getExpectedTypeByParent(context);
+ if (targetType == null) {
+ final PsiElement parent = PsiUtil.skipParenthesizedExprUp(context.getParent());
+ if (parent instanceof PsiExpressionList) {
+ final PsiElement gParent = parent.getParent();
+ if (gParent instanceof PsiCallExpression) {
+ final PsiExpressionList argumentList = ((PsiCallExpression)gParent).getArgumentList();
+ if (argumentList != null) {
+ final JavaResolveResult resolveResult = ((PsiCallExpression)gParent).resolveMethodGenerics();
+ final PsiElement parentMethod = resolveResult.getElement();
+ if (parentMethod instanceof PsiMethod) {
+ final PsiParameter[] parameters = ((PsiMethod)parentMethod).getParameterList().getParameters();
+ PsiElement arg = context;
+ while (arg.getParent() instanceof PsiParenthesizedExpression) {
+ arg = parent.getParent();
+ }
+ final PsiExpression[] args = argumentList.getExpressions();
+ targetType = getParameterType(parameters, args, ArrayUtilRt.find(args, arg), resolveResult.getSubstitutor());
+ }
+ }
+ }
+ } else if (parent instanceof PsiConditionalExpression) {
+ targetType = PsiTypesUtil.getExpectedTypeByParent((PsiExpression)parent);
+ }
+ }
if (targetType != null) {
- myConstraints.add(new TypeCompatibilityConstraint(targetType, returnType));
+ myConstraints.add(new TypeCompatibilityConstraint(targetType, PsiImplUtil.normalizeWildcardTypeByPosition(returnType, context)));
}
}
}
}
public InferenceVariable getInferenceVariable(PsiType psiType) {
+ return getInferenceVariable(psiType, true);
+ }
+
+ public InferenceVariable getInferenceVariable(PsiType psiType, boolean acceptCaptured) {
final PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(psiType);
if (psiClass instanceof PsiTypeParameter) {
final InferenceVariable inferenceVariable = myInferenceVariables.get(psiClass);
- if (inferenceVariable != null) {
+ if (inferenceVariable != null && (acceptCaptured || !inferenceVariable.isCaptured())) {
return inferenceVariable;
}
}
@@ -162,10 +255,16 @@ public class InferenceSession {
}
public boolean isProperType(@Nullable PsiType type) {
- return collectDependencies(type, null);
+ return isProperType(type, true);
}
- public boolean collectDependencies(@Nullable PsiType type, @Nullable final Set<InferenceVariable> dependencies) {
+ public boolean isProperType(@Nullable PsiType type, boolean acceptCaptured) {
+ return collectDependencies(type, null, acceptCaptured);
+ }
+
+ public boolean collectDependencies(@Nullable PsiType type,
+ @Nullable final Set<InferenceVariable> dependencies,
+ final boolean acceptCaptured) {
if (type == null) return true;
final Boolean isProper = type.accept(new PsiTypeVisitor<Boolean>() {
@Nullable
@@ -191,7 +290,7 @@ public class InferenceSession {
@Nullable
@Override
public Boolean visitClassType(PsiClassType classType) {
- final InferenceVariable inferenceVariable = getInferenceVariable(classType);
+ final InferenceVariable inferenceVariable = getInferenceVariable(classType, acceptCaptured);
if (inferenceVariable != null) {
if (dependencies != null) {
dependencies.add(inferenceVariable);
@@ -225,7 +324,7 @@ public class InferenceSession {
List<ConstraintFormula> newConstraints = new ArrayList<ConstraintFormula>();
for (int i = myConstraintIdx; i < myConstraints.size(); i++) {
ConstraintFormula constraint = myConstraints.get(i);
- if (!constraint.reduce(this, newConstraints, myDelayedConstraints)) {
+ if (!constraint.reduce(this, newConstraints)) {
return false;
}
}
@@ -241,7 +340,7 @@ public class InferenceSession {
for (List<InferenceVariable> variables : independentVars) {
for (InferenceVariable inferenceVariable : variables) {
- if (inferenceVariable.getInstantiation() != PsiType.NULL) continue;
+ if (inferenceVariable.isCaptured() || inferenceVariable.getInstantiation() != PsiType.NULL) continue;
final PsiTypeParameter typeParameter = inferenceVariable.getParameter();
try {
final List<PsiType> eqBounds = inferenceVariable.getBounds(InferenceBound.EQ);
@@ -253,19 +352,18 @@ public class InferenceSession {
}
PsiType bound = null;
for (PsiType eqBound : eqBounds) {
- eqBound = acceptBoundsWithRecursiveDependencies(typeParameter, eqBound);
- if (isProperType(eqBound)) {
- bound = eqBound;
- break;
- }
+ bound = acceptBoundsWithRecursiveDependencies(typeParameter, eqBound);
}
if (bound != null) {
+ if (bound instanceof PsiCapturedWildcardType && eqBounds.size() > 1) {
+ continue;
+ }
inferenceVariable.setInstantiation(bound);
} else {
PsiType lub = null;
for (PsiType lowerBound : lowerBounds) {
lowerBound = acceptBoundsWithRecursiveDependencies(typeParameter, lowerBound);
- if (isProperType(lowerBound)) {
+ if (isProperType(lowerBound, false)) {
if (lub == null) {
lub = lowerBound;
}
@@ -281,7 +379,7 @@ public class InferenceSession {
PsiType glb = null;
for (PsiType upperBound : upperBounds) {
upperBound = acceptBoundsWithRecursiveDependencies(typeParameter, upperBound);
- if (isProperType(upperBound)) {
+ if (isProperType(upperBound, false)) {
if (glb == null) {
glb = upperBound;
}
@@ -307,8 +405,9 @@ public class InferenceSession {
}
private PsiType acceptBoundsWithRecursiveDependencies(PsiTypeParameter typeParameter, PsiType bound) {
- if (PsiPolyExpressionUtil.mentionsTypeParameters(bound, Collections.singleton(typeParameter))) {
- return mySiteSubstitutor.put(typeParameter, null).substitute(bound);
+ if (!isProperType(bound)) {
+ final PsiSubstitutor substitutor = PsiUtil.resolveClassInType(bound) != typeParameter ? mySiteSubstitutor.put(typeParameter, null) : mySiteSubstitutor;
+ return substitutor.substitute(bound);
}
return bound;
}
@@ -330,4 +429,24 @@ public class InferenceSession {
myConstraints.add(constraint);
}
}
+
+ public Collection<PsiTypeParameter> getTypeParams() {
+ return myInferenceVariables.keySet();
+ }
+
+ public void addVariable(PsiTypeParameter typeParameter, final PsiType parameter) {
+ InferenceVariable variable = new InferenceVariable(typeParameter);
+ if (parameter instanceof PsiWildcardType) {
+ PsiType bound = ((PsiWildcardType)parameter).getBound();
+ if (bound != null) {
+ variable.addBound(bound, ((PsiWildcardType)parameter).isExtends() ? InferenceBound.UPPER : InferenceBound.LOWER);
+ } else {
+ variable.addBound(PsiType.getJavaLangObject(typeParameter.getManager(), parameter.getResolveScope()),
+ InferenceBound.UPPER);
+ }
+ } else {
+ variable.addBound(parameter, InferenceBound.EQ);
+ }
+ myInferenceVariables.put(typeParameter, variable);
+ }
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java
index e69f229fe91f..f750e1247728 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java
@@ -58,7 +58,8 @@ public class InferenceVariable {
list = new ArrayList<PsiType>();
myBounds.put(inferenceBound, list);
}
- if (!list.contains(classType)) {
+ final int idx = list.indexOf(classType);
+ if (idx < 0 || inferenceBound == InferenceBound.EQ && classType instanceof PsiCapturedWildcardType && list.get(idx) != classType) {
list.add(classType);
return true;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariablesOrder.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariablesOrder.java
index 4a2c4126611e..c27ae4a53916 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariablesOrder.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariablesOrder.java
@@ -41,7 +41,7 @@ public class InferenceVariablesOrder {
for (InferenceBound inferenceBound : InferenceBound.values()) {
for (PsiType bound : var.getBounds(inferenceBound)) {
final HashSet<InferenceVariable> dependencies = new HashSet<InferenceVariable>();
- session.collectDependencies(bound, dependencies);
+ session.collectDependencies(bound, dependencies, true);
for (InferenceVariable dependentVariable : dependencies) {
final InferenceGraphNode<InferenceVariable> dependency = nodes.get(dependentVariable);
if (dependency != null) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java
index 2e425e0fb436..d6a1d46ad336 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java
@@ -82,10 +82,6 @@ public class PsiPolyExpressionUtil {
return false;
}
- public static PsiType getTargetType(@NotNull PsiCallExpression expression) {
- return PsiTypesUtil.getExpectedTypeByParent(expression);
- }
-
public static Boolean mentionsTypeParameters(@Nullable PsiType returnType, final Set<PsiTypeParameter> typeParameters) {
if (returnType == null) return false;
return returnType.accept(new PsiTypeVisitor<Boolean>() {
@@ -125,7 +121,7 @@ public class PsiPolyExpressionUtil {
private static boolean isInAssignmentOrInvocationContext(PsiExpression expr) {
final PsiElement context = expr.getParent();
- return context instanceof PsiExpressionList || isAssignmentContext(expr, context);
+ return context instanceof PsiExpressionList || context instanceof PsiConditionalExpression || isAssignmentContext(expr, context);
}
private static boolean isAssignmentContext(PsiExpression expr, PsiElement context) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java
new file mode 100644
index 000000000000..19f50e6fd412
--- /dev/null
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.impl.source.resolve.graphInference.constraints;
+
+import com.intellij.codeInsight.ExceptionUtil;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
+import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * User: anna
+ */
+public class CheckedExceptionCompatibilityConstraint extends InputOutputConstraintFormula {
+ private static final Logger LOG = Logger.getInstance("#" + CheckedExceptionCompatibilityConstraint.class.getName());
+ private final PsiExpression myExpression;
+ private final PsiType myT;
+
+ public CheckedExceptionCompatibilityConstraint(PsiExpression expression, PsiType t) {
+ myExpression = expression;
+ myT = t;
+ }
+
+ @Override
+ public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
+ if (!PsiPolyExpressionUtil.isPolyExpression(myExpression) ||
+ myExpression instanceof PsiCallExpression) {
+ return true;
+ }
+ if (myExpression instanceof PsiParenthesizedExpression) {
+ constraints.add(new CheckedExceptionCompatibilityConstraint(((PsiParenthesizedExpression)myExpression).getExpression(), myT));
+ return true;
+ }
+ if (myExpression instanceof PsiConditionalExpression) {
+ final PsiExpression thenExpression = ((PsiConditionalExpression)myExpression).getThenExpression();
+ if (thenExpression != null) {
+ constraints.add(new CheckedExceptionCompatibilityConstraint(thenExpression, myT));
+ }
+ final PsiExpression elseExpression = ((PsiConditionalExpression)myExpression).getElseExpression();
+ if (elseExpression != null) {
+ constraints.add(new CheckedExceptionCompatibilityConstraint(elseExpression, myT));
+ }
+ return true;
+ }
+ if (myExpression instanceof PsiLambdaExpression || myExpression instanceof PsiMethodReferenceExpression) {
+ if (LambdaHighlightingUtil.checkInterfaceFunctional(myT) != null) {
+ return false;
+ }
+ final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(myT);
+ if (interfaceMethod == null) {
+ return false;
+ }
+
+ final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, PsiUtil.resolveGenericsClassInType(myT));
+ for (PsiParameter parameter : interfaceMethod.getParameterList().getParameters()) {
+ if (!session.isProperType(substitutor.substitute(parameter.getType()))) return false;
+ }
+ final PsiType returnType = interfaceMethod.getReturnType();
+ LOG.assertTrue(returnType != null, interfaceMethod);
+ if (!session.isProperType(substitutor.substitute(returnType))) return false;
+
+ final List<PsiType>
+ expectedThrownTypes = ContainerUtil.map(interfaceMethod.getThrowsList().getReferencedTypes(), new Function<PsiType, PsiType>() {
+ @Override
+ public PsiType fun(PsiType type) {
+ return substitutor.substitute(type);
+ }
+ });
+ final List<PsiType> expectedNonProperThrownTypes = new ArrayList<PsiType>();
+ for (PsiType type : expectedThrownTypes) {
+ if (!session.isProperType(type)) {
+ expectedNonProperThrownTypes.add(type);
+ }
+ }
+
+ final List<PsiType> thrownTypes = new ArrayList<PsiType>();
+ if (myExpression instanceof PsiLambdaExpression) {
+ //todo
+ } else {
+ final PsiElement resolve = ((PsiMethodReferenceExpression)myExpression).resolve();
+ if (resolve instanceof PsiMethod) {
+ for (PsiClassType type : ((PsiMethod)resolve).getThrowsList().getReferencedTypes()) {
+ if (!ExceptionUtil.isUncheckedException(type)) {
+ thrownTypes.add(type);
+ }
+ }
+ }
+ }
+
+ if (expectedNonProperThrownTypes.isEmpty()) {
+ for (PsiType thrownType : thrownTypes) {
+ if (!isAddressed(expectedThrownTypes, thrownType)) return false;
+ }
+ } else {
+ final ArrayList<PsiType> expectedProperTypes = new ArrayList<PsiType>(expectedThrownTypes);
+ expectedProperTypes.retainAll(expectedNonProperThrownTypes);
+ for (PsiType thrownType : thrownTypes) {
+ if (!isAddressed(expectedProperTypes, thrownType)) {
+ for (PsiType expectedNonProperThrownType : expectedNonProperThrownTypes) {
+ constraints.add(new TypeCompatibilityConstraint(expectedNonProperThrownType, thrownType));
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private static boolean isAddressed(List<PsiType> expectedThrownTypes, PsiType thrownType) {
+ for (PsiType expectedThrownType : expectedThrownTypes) {
+ if (TypeConversionUtil.isAssignable(expectedThrownType, thrownType)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ protected PsiExpression getExpression() {
+ return myExpression;
+ }
+
+ @Override
+ protected PsiType getT() {
+ return myT;
+ }
+
+ @Override
+ protected InputOutputConstraintFormula createSelfConstraint(PsiType type, PsiExpression expression) {
+ return new CheckedExceptionCompatibilityConstraint(expression, type);
+ }
+
+ @Override
+ protected void collectReturnTypeVariables(InferenceSession session,
+ PsiExpression psiExpression,
+ PsiMethod interfaceMethod,
+ Set<InferenceVariable> result) {
+ final PsiType returnType = interfaceMethod.getReturnType();
+ session.collectDependencies(returnType, result, true);
+ }
+}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ConstraintFormula.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ConstraintFormula.java
index 992d875bb535..8dc8ee034cc1 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ConstraintFormula.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ConstraintFormula.java
@@ -23,5 +23,5 @@ import java.util.List;
* User: anna
*/
public interface ConstraintFormula {
- boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints);
+ boolean reduce(InferenceSession session, List<ConstraintFormula> constraints);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
index a0e6a767d8f2..7084538c17c7 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
@@ -15,18 +15,22 @@
*/
package com.intellij.psi.impl.source.resolve.graphInference.constraints;
+import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
+import com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl;
+import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.TypeConversionUtil;
import org.jetbrains.annotations.NotNull;
-import java.util.List;
+import java.util.*;
/**
* User: anna
*/
-public class ExpressionCompatibilityConstraint implements ConstraintFormula {
+public class ExpressionCompatibilityConstraint extends InputOutputConstraintFormula {
private PsiExpression myExpression;
private PsiType myT;
@@ -36,7 +40,7 @@ public class ExpressionCompatibilityConstraint implements ConstraintFormula {
}
@Override
- public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints) {
+ public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
if (session.isProperType(myT)) {
return TypeConversionUtil.areTypesAssignmentCompatible(myT, myExpression);
}
@@ -69,11 +73,59 @@ public class ExpressionCompatibilityConstraint implements ConstraintFormula {
}
if (myExpression instanceof PsiCallExpression) {
- //todo
+ final PsiExpressionList argumentList = ((PsiCallExpression)myExpression).getArgumentList();
+ if (argumentList != null) {
+ final Map<PsiElement,Pair<PsiMethod,PsiSubstitutor>> map = MethodCandidateInfo.CURRENT_CANDIDATE.get();
+ final Pair<PsiMethod,PsiSubstitutor> pair = map != null ? map.get(argumentList) : null;
+ final PsiMethod method = pair != null ? pair.first : ((PsiCallExpression)myExpression).resolveMethod();
+ PsiType returnType = null;
+ InferenceSession callSession = null;
+ if (method != null) {
+ returnType = method.getReturnType();
+ final PsiParameter[] parameters = method.getParameterList().getParameters();
+ if (returnType != null) {
+ callSession = new InferenceSession(method.getTypeParameters(), parameters,
+ argumentList.getExpressions(),
+ PsiSubstitutor.EMPTY, null, myExpression.getManager());
+
+ }
+ } else if (myExpression instanceof PsiNewExpression) { //default constructor
+ final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)myExpression).getClassOrAnonymousClassReference();
+ if (classReference != null) {
+ final PsiElement psiClass = classReference.resolve();
+ if (psiClass instanceof PsiClass) {
+ returnType = JavaPsiFacade.getElementFactory(argumentList.getProject()).createType((PsiClass)psiClass, PsiSubstitutor.EMPTY);
+ callSession = new InferenceSession(((PsiClass)psiClass).getTypeParameters(),
+ PsiParameter.EMPTY_ARRAY,
+ argumentList.getExpressions(),
+ PsiSubstitutor.EMPTY, null, myExpression.getManager());
+ }
+ }
+ }
+
+ if (callSession != null) {
+
+ for (PsiTypeParameter typeParameter : session.getTypeParams()) {
+ callSession.addCapturedVariable(typeParameter);
+ }
+ callSession.addConstraint(new TypeCompatibilityConstraint(myT, returnType));
+ final PsiSubstitutor callSubstitutor = callSession.infer();
+
+ if (myExpression instanceof PsiMethodCallExpression) {
+ returnType = PsiMethodCallExpressionImpl.captureReturnType((PsiMethodCallExpression)myExpression, method, returnType, callSubstitutor);
+ }
+ else {
+ returnType = callSubstitutor.substitute(returnType);
+ }
+ constraints.add(new TypeCompatibilityConstraint(myT, returnType)); //todo primitive types
+ }
+ }
+ return true;
}
if (myExpression instanceof PsiMethodReferenceExpression) {
- //todo
+ constraints.add(new PsiMethodReferenceCompatibilityConstraint(((PsiMethodReferenceExpression)myExpression), myT));
+ return true;
}
if (myExpression instanceof PsiLambdaExpression) {
@@ -104,4 +156,37 @@ public class ExpressionCompatibilityConstraint implements ConstraintFormula {
result = 31 * result + myT.hashCode();
return result;
}
+
+ @Override
+ public PsiExpression getExpression() {
+ return myExpression;
+ }
+
+ @Override
+ public PsiType getT() {
+ return myT;
+ }
+
+ @Override
+ protected InputOutputConstraintFormula createSelfConstraint(PsiType type, PsiExpression expression) {
+ return new ExpressionCompatibilityConstraint(expression, type);
+ }
+
+ protected void collectReturnTypeVariables(InferenceSession session,
+ PsiExpression psiExpression,
+ PsiMethod interfaceMethod,
+ Set<InferenceVariable> result) {
+ if (psiExpression instanceof PsiLambdaExpression) {
+ final PsiType returnType = interfaceMethod.getReturnType();
+ if (returnType != PsiType.VOID) {
+ final List<PsiExpression> returnExpressions = LambdaUtil.getReturnExpressions((PsiLambdaExpression)psiExpression);
+ for (PsiExpression expression : returnExpressions) {
+ final Set<InferenceVariable> resultInputVars = createSelfConstraint(returnType, expression).getInputVariables(session);
+ if (resultInputVars != null) {
+ result.addAll(resultInputVars);
+ }
+ }
+ }
+ }
+ }
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/InputOutputConstraintFormula.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/InputOutputConstraintFormula.java
new file mode 100644
index 000000000000..d06538c06b41
--- /dev/null
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/InputOutputConstraintFormula.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.impl.source.resolve.graphInference.constraints;
+
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
+import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
+import com.intellij.psi.util.PsiUtil;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * User: anna
+ * Date: 9/25/13
+ */
+public abstract class InputOutputConstraintFormula implements ConstraintFormula {
+
+ protected abstract PsiExpression getExpression();
+ protected abstract PsiType getT();
+ protected abstract InputOutputConstraintFormula createSelfConstraint(PsiType type, PsiExpression expression);
+ protected abstract void collectReturnTypeVariables(InferenceSession session,
+ PsiExpression psiExpression,
+ PsiMethod interfaceMethod,
+ Set<InferenceVariable> result);
+
+ public Set<InferenceVariable> getInputVariables(InferenceSession session) {
+ final PsiExpression psiExpression = getExpression();
+ if (PsiPolyExpressionUtil.isPolyExpression(psiExpression)) {
+ final PsiType type = getT();
+ if (psiExpression instanceof PsiLambdaExpression || psiExpression instanceof PsiMethodReferenceExpression) {
+ final InferenceVariable inferenceVariable = session.getInferenceVariable(type);
+ if (inferenceVariable != null) {
+ return Collections.singleton(inferenceVariable);
+ }
+ final PsiType functionalInterfaceType = psiExpression instanceof PsiLambdaExpression
+ ? ((PsiLambdaExpression)psiExpression).getFunctionalInterfaceType()
+ : ((PsiMethodReferenceExpression)psiExpression).getFunctionalInterfaceType();
+ if (functionalInterfaceType != null) {
+ final PsiType functionType =
+ psiExpression instanceof PsiLambdaExpression
+ ? FunctionalInterfaceParameterizationUtil.getFunctionalType(functionalInterfaceType, (PsiLambdaExpression)psiExpression)
+ : functionalInterfaceType;
+ final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionType);
+ final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
+ if (interfaceMethod != null) {
+
+ final Set<InferenceVariable> result = new HashSet<InferenceVariable>();
+ final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, resolveResult);
+ for (PsiParameter parameter : interfaceMethod.getParameterList().getParameters()) {
+ session.collectDependencies(substitutor.substitute(parameter.getType()), result, true);
+ }
+
+ collectReturnTypeVariables(session, psiExpression, interfaceMethod, result);
+
+ return result;
+ }
+ }
+ }
+
+ if (psiExpression instanceof PsiParenthesizedExpression) {
+ final PsiExpression expression = ((PsiParenthesizedExpression)psiExpression).getExpression();
+ return expression != null ? createSelfConstraint(type, expression).getInputVariables(session) : null;
+ }
+
+ if (psiExpression instanceof PsiConditionalExpression) {
+ final PsiExpression thenExpression = ((PsiConditionalExpression)psiExpression).getThenExpression();
+ final PsiExpression elseExpression = ((PsiConditionalExpression)psiExpression).getElseExpression();
+ final Set<InferenceVariable> thenResult = thenExpression != null ? createSelfConstraint(type, thenExpression).getInputVariables(session) : null;
+ final Set<InferenceVariable> elseResult = elseExpression != null ? createSelfConstraint(type, elseExpression).getInputVariables(session) : null;
+ if (thenResult == null) {
+ return elseResult;
+ } else if (elseResult == null) {
+ return thenResult;
+ } else {
+ thenResult.addAll(elseResult);
+ return thenResult;
+ }
+ }
+ }
+ return null;
+ }
+
+
+ @Nullable
+ public Set<InferenceVariable> getOutputVariables(Set<InferenceVariable> inputVariables, InferenceSession session) {
+ if (!PsiPolyExpressionUtil.isPolyExpression(getExpression())) {
+ final HashSet<InferenceVariable> mentionedVariables = new HashSet<InferenceVariable>();
+ session.collectDependencies(getT(), mentionedVariables, true);
+ mentionedVariables.removeAll(inputVariables);
+ return mentionedVariables;
+ }
+ return null;
+ }
+}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java
index 9d9dad46ffc8..d7751754ab8b 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java
@@ -1,8 +1,8 @@
package com.intellij.psi.impl.source.resolve.graphInference.constraints;
import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
-import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
import com.intellij.psi.util.PsiUtil;
import java.util.List;
@@ -20,30 +20,21 @@ public class LambdaExpressionCompatibilityConstraint implements ConstraintFormul
}
@Override
- public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints) {
- final InferenceVariable inferenceVariable = session.getInferenceVariable(myT);
- if (inferenceVariable != null) {
- delayedConstraints.add(this);
- return true;
- }
+ public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
if (LambdaHighlightingUtil.checkInterfaceFunctional(myT) != null) {
return false;
}
if (myExpression.hasFormalParameterTypes()) {
}
- final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(myT);
+ final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(
+ FunctionalInterfaceParameterizationUtil.getFunctionalType(myT, myExpression));
+ final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
if (interfaceMethod == null) {
return false;
}
- final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, PsiUtil.resolveGenericsClassInType(myT));
+ final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, resolveResult);
final PsiParameter[] parameters = interfaceMethod.getParameterList().getParameters();
- for (PsiParameter parameter : parameters) {
- if (!session.isProperType(parameter.getType())) {
- delayedConstraints.add(this);
- return true;
- }
- }
final PsiParameter[] lambdaParameters = myExpression.getParameterList().getParameters();
if (lambdaParameters.length != parameters.length) {
@@ -53,20 +44,27 @@ public class LambdaExpressionCompatibilityConstraint implements ConstraintFormul
for (int i = 0; i < lambdaParameters.length; i++) {
constraints.add(new TypeEqualityConstraint(lambdaParameters[i].getType(), substitutor.substitute(parameters[i].getType())));
}
+ } else {
+ for (PsiParameter parameter : parameters) {
+ if (!session.isProperType(substitutor.substitute(parameter.getType()))) {
+ return false;
+ }
+ }
}
final PsiType returnType = interfaceMethod.getReturnType();
if (returnType != null) {
+ final List<PsiExpression> returnExpressions = LambdaUtil.getReturnExpressions(myExpression);
if (returnType.equals(PsiType.VOID)) {
- if (!myExpression.isVoidCompatible() && !(myExpression.getBody() instanceof PsiExpression)) {
+ if (!returnExpressions.isEmpty() && !(myExpression.getBody() instanceof PsiExpression)) {
return false;
}
} else {
- if (myExpression.isVoidCompatible()) { //not value-compatible
+ if (returnExpressions.isEmpty()) { //not value-compatible
return false;
}
- for (PsiExpression returnExpressions : LambdaUtil.getReturnExpressions(myExpression)) {
- constraints.add(new ExpressionCompatibilityConstraint(returnExpressions, returnType));
+ for (PsiExpression returnExpression : returnExpressions) {
+ constraints.add(new ExpressionCompatibilityConstraint(returnExpression, substitutor.substitute(returnType)));
}
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java
new file mode 100644
index 000000000000..d1de66e453a8
--- /dev/null
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.impl.source.resolve.graphInference.constraints;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
+import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
+import com.intellij.psi.util.PsiUtil;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * User: anna
+ */
+public class PsiMethodReferenceCompatibilityConstraint implements ConstraintFormula {
+ private static final Logger LOG = Logger.getInstance("#" + PsiMethodReferenceCompatibilityConstraint.class.getName());
+ private final PsiMethodReferenceExpression myExpression;
+ private final PsiType myT;
+
+ public PsiMethodReferenceCompatibilityConstraint(PsiMethodReferenceExpression expression, PsiType t) {
+ myExpression = expression;
+ myT = t;
+ }
+
+ @Override
+ public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
+ if (LambdaHighlightingUtil.checkInterfaceFunctional(myT) != null) {
+ return false;
+ }
+
+ final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(myT);
+ if (interfaceMethod == null) {
+ return false;
+ }
+
+ final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, PsiUtil.resolveGenericsClassInType(myT));
+ final PsiParameter[] parameters = interfaceMethod.getParameterList().getParameters();
+ for (PsiParameter parameter : parameters) {
+ if (!session.isProperType(substitutor.substitute(parameter.getType()))) {
+ return false;
+ }
+ }
+
+ final PsiElement resolve = myExpression.resolve();
+ if (resolve == null) {
+ return false;
+ }
+
+ final PsiType returnType = interfaceMethod.getReturnType();
+ LOG.assertTrue(returnType != null, interfaceMethod);
+ if (PsiType.VOID.equals(returnType)) {
+ return true;
+ }
+
+ if (resolve instanceof PsiMethod) {
+ final PsiMethod method = (PsiMethod)resolve;
+ final PsiType referencedMethodReturnType;
+ if (method.isConstructor()) {
+ final PsiClass containingClass = method.getContainingClass();
+ LOG.assertTrue(containingClass != null, method);
+ referencedMethodReturnType = JavaPsiFacade.getElementFactory(method.getProject()).createType(containingClass);
+ }
+ else {
+ referencedMethodReturnType = method.getReturnType();
+ }
+ LOG.assertTrue(referencedMethodReturnType != null, method);
+
+ if (myExpression.getTypeParameters().length == 0 &&
+ ((PsiMethod)resolve).getTypeParameters().length > 0 &&
+ PsiPolyExpressionUtil.mentionsTypeParameters(returnType, new HashSet<PsiTypeParameter>(Arrays.asList(interfaceMethod.getTypeParameters())))) {
+ //todo target type constraint
+ return true;
+ }
+
+ if (PsiType.VOID.equals(referencedMethodReturnType)) {
+ return false;
+ }
+
+ constraints.add(new TypeCompatibilityConstraint(substitutor.substitute(returnType), referencedMethodReturnType));
+ }
+
+ return true;
+ }
+}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/SubtypingConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/SubtypingConstraint.java
index 64c28d1b462f..e2677bf7a6b3 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/SubtypingConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/SubtypingConstraint.java
@@ -20,7 +20,6 @@ import com.intellij.psi.impl.source.resolve.graphInference.InferenceBound;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
import com.intellij.psi.util.TypeConversionUtil;
-import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -39,7 +38,7 @@ public class SubtypingConstraint implements ConstraintFormula {
}
@Override
- public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints) {
+ public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
if (myIsRefTypes) {
if (session.isProperType(myS) && session.isProperType(myT)) {
if (myT == null || myS == null) return myS == myT;
@@ -127,6 +126,11 @@ public class SubtypingConstraint implements ConstraintFormula {
}
return false;
} else {
+
+ if (myS instanceof PsiCapturedWildcardType) {
+ myS = ((PsiCapturedWildcardType)myS).getWildcard();
+ }
+
if (myS instanceof PsiWildcardType) {
final PsiType sBound = ((PsiWildcardType)myS).getBound();
if (sBound != null && ((PsiWildcardType)myS).isSuper()) {
@@ -140,9 +144,19 @@ public class SubtypingConstraint implements ConstraintFormula {
}
return false;
} else {
+ InferenceVariable inferenceVariable = session.getInferenceVariable(myT);
if (myS instanceof PsiWildcardType) {
- return false;
+ return inferenceVariable != null && inferenceVariable.isCaptured();
} else {
+ if (inferenceVariable != null) {
+ inferenceVariable.addBound(myS, InferenceBound.EQ);
+ return true;
+ }
+ inferenceVariable = session.getInferenceVariable(myS);
+ if (inferenceVariable != null) {
+ inferenceVariable.addBound(myT, InferenceBound.EQ);
+ return true;
+ }
constraints.add(new SubtypingConstraint(myT, myS, true));
return true;
}
@@ -159,6 +173,9 @@ public class SubtypingConstraint implements ConstraintFormula {
SubtypingConstraint that = (SubtypingConstraint)o;
if (myIsRefTypes != that.myIsRefTypes) return false;
+
+ if (!myIsRefTypes && myS instanceof PsiCapturedWildcardType && myS != that.myS) return false;
+
if (myS != null ? !myS.equals(that.myS) : that.myS != null) return false;
if (myT != null ? !myT.equals(that.myT) : that.myT != null) return false;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeCompatibilityConstraint.java
index 353f03b66a80..cd9ec95f1d0d 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeCompatibilityConstraint.java
@@ -37,7 +37,7 @@ public class TypeCompatibilityConstraint implements ConstraintFormula {
}
@Override
- public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints) {
+ public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
if (session.isProperType(myT) && session.isProperType(myS)) {
return TypeConversionUtil.isAssignable(myS, myT);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java
index a71465653a6f..06e7b2b101ad 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java
@@ -38,7 +38,7 @@ public class TypeEqualityConstraint implements ConstraintFormula {
}
@Override
- public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints) {
+ public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
if (session.isProperType(myT) && session.isProperType(myS)) {
return myT.equals(myS);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerExpressionImpl.java
index 4e2300fcf687..80b7e94f972b 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerExpressionImpl.java
@@ -18,24 +18,23 @@ package com.intellij.psi.impl.source.tree.java;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.Constants;
import com.intellij.psi.impl.source.tree.*;
-import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.ChildRoleBase;
+import com.intellij.psi.tree.IElementType;
import com.intellij.util.CharTable;
import org.jetbrains.annotations.NotNull;
-public class PsiArrayInitializerExpressionImpl extends ExpressionPsiElement implements PsiArrayInitializerExpression, Constants {
+public class PsiArrayInitializerExpressionImpl extends ExpressionPsiElement implements PsiArrayInitializerExpression {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiArrayInitializerExpressionImpl");
public PsiArrayInitializerExpressionImpl() {
- super(ARRAY_INITIALIZER_EXPRESSION);
+ super(JavaElementType.ARRAY_INITIALIZER_EXPRESSION);
}
@Override
@NotNull
public PsiExpression[] getInitializers(){
- return getChildrenAsPsiElements(EXPRESSION_BIT_SET, PsiExpression.ARRAY_FACTORY);
+ return getChildrenAsPsiElements(ElementType.EXPRESSION_BIT_SET, PsiExpression.ARRAY_FACTORY);
}
@Override
@@ -69,10 +68,10 @@ public class PsiArrayInitializerExpressionImpl extends ExpressionPsiElement impl
return null;
case ChildRole.LBRACE:
- return findChildByType(LBRACE);
+ return findChildByType(JavaTokenType.LBRACE);
case ChildRole.RBRACE:
- return findChildByType(RBRACE);
+ return findChildByType(JavaTokenType.RBRACE);
}
}
@@ -80,17 +79,17 @@ public class PsiArrayInitializerExpressionImpl extends ExpressionPsiElement impl
public int getChildRole(ASTNode child) {
LOG.assertTrue(child.getTreeParent() == this);
IElementType i = child.getElementType();
- if (i == COMMA) {
+ if (i == JavaTokenType.COMMA) {
return ChildRole.COMMA;
}
- else if (i == LBRACE) {
+ else if (i == JavaTokenType.LBRACE) {
return ChildRole.LBRACE;
}
- else if (i == RBRACE) {
+ else if (i == JavaTokenType.RBRACE) {
return ChildRole.RBRACE;
}
else {
- if (EXPRESSION_BIT_SET.contains(child.getElementType())) {
+ if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType())) {
return ChildRole.EXPRESSION_IN_LIST;
}
return ChildRoleBase.NONE;
@@ -129,17 +128,17 @@ public class PsiArrayInitializerExpressionImpl extends ExpressionPsiElement impl
if (ElementType.EXPRESSION_BIT_SET.contains(first.getElementType())) {
final CharTable charTab = SharedImplUtil.findCharTableByTree(this);
for (ASTNode child = first.getTreeNext(); child != null; child = child.getTreeNext()) {
- if (child.getElementType() == COMMA) break;
+ if (child.getElementType() == JavaTokenType.COMMA) break;
if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType())) {
- TreeElement comma = Factory.createSingleLeafElement(COMMA, ",", 0, 1, charTab, getManager());
+ TreeElement comma = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, charTab, getManager());
super.addInternal(comma, comma, first, Boolean.FALSE);
break;
}
}
for (ASTNode child = first.getTreePrev(); child != null; child = child.getTreePrev()) {
- if (child.getElementType() == COMMA) break;
+ if (child.getElementType() == JavaTokenType.COMMA) break;
if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType())) {
- TreeElement comma = Factory.createSingleLeafElement(COMMA, ",", 0, 1, charTab, getManager());
+ TreeElement comma = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, charTab, getManager());
super.addInternal(comma, comma, child, Boolean.FALSE);
break;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java
index 3093099e228a..5091ea053471 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java
@@ -19,6 +19,7 @@ import com.intellij.lang.ASTNode;
import com.intellij.psi.*;
import com.intellij.psi.controlFlow.*;
import com.intellij.psi.impl.PsiImplUtil;
+import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
import com.intellij.psi.impl.source.tree.ChildRole;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.scope.PsiScopeProcessor;
@@ -63,7 +64,7 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi
@Nullable
@Override
public PsiType getFunctionalInterfaceType() {
- return LambdaUtil.getFunctionalInterfaceType(this, true);
+ return FunctionalInterfaceParameterizationUtil.getFunctionalType(LambdaUtil.getFunctionalInterfaceType(this, true), this);
}
@Override
@@ -118,6 +119,6 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi
for (PsiParameter parameter : parameters) {
if (parameter.getTypeElement() == null) return false;
}
- return parameters.length > 0;
+ return true;
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java
index 1dd74f133dcf..36013c3625a3 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java
@@ -170,7 +170,7 @@ public class PsiMethodCallExpressionImpl extends ExpressionPsiElement implements
}
@Nullable
- private static PsiType getResultType(PsiExpression call,
+ private static PsiType getResultType(PsiMethodCallExpression call,
PsiReferenceExpression methodExpression,
JavaResolveResult result,
@NotNull final LanguageLevel languageLevel) {
@@ -196,40 +196,46 @@ public class PsiMethodCallExpressionImpl extends ExpressionPsiElement implements
ret = ((PsiClassType)ret).setLanguageLevel(languageLevel);
}
if (is15OrHigher) {
- final PsiSubstitutor substitutor = result.getSubstitutor();
- PsiType substitutedReturnType = substitutor.substitute(ret);
- if (substitutedReturnType == null) return TypeConversionUtil.erasure(ret);
- if (PsiUtil.isRawSubstitutor(method, substitutor)) {
- final PsiType returnTypeErasure = TypeConversionUtil.erasure(ret);
- if (Comparing.equal(TypeConversionUtil.erasure(substitutedReturnType), returnTypeErasure)) {
- return returnTypeErasure;
- }
- }
- PsiType lowerBound = PsiType.NULL;
- if (substitutedReturnType instanceof PsiCapturedWildcardType) {
- lowerBound = ((PsiCapturedWildcardType)substitutedReturnType).getLowerBound();
- } else if (substitutedReturnType instanceof PsiWildcardType) {
- lowerBound = ((PsiWildcardType)substitutedReturnType).getSuperBound();
- }
- if (lowerBound != PsiType.NULL) { //? super
- final PsiClass containingClass = method.getContainingClass();
- final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
- final PsiClass childClass = qualifierExpression != null ? PsiUtil.resolveClassInClassTypeOnly(qualifierExpression.getType()) : null;
- if (containingClass != null && childClass != null) {
- final PsiType typeInChildClassTypeParams = TypeConversionUtil.getSuperClassSubstitutor(containingClass, childClass, PsiSubstitutor.EMPTY).substitute(ret);
- final PsiClass substituted = PsiUtil.resolveClassInClassTypeOnly(typeInChildClassTypeParams);
- if (substituted instanceof PsiTypeParameter) {
- final PsiClassType[] extendsListTypes = substituted.getExtendsListTypes();
- if (extendsListTypes.length == 1) {
- return extendsListTypes[0];
- }
- }
+ return captureReturnType(call, method, ret, result.getSubstitutor());
+ }
+ return TypeConversionUtil.erasure(ret);
+ }
+ }
+
+ public static PsiType captureReturnType(PsiMethodCallExpression call,
+ PsiMethod method,
+ PsiType ret,
+ PsiSubstitutor substitutor) {
+ PsiType substitutedReturnType = substitutor.substitute(ret);
+ if (substitutedReturnType == null) return TypeConversionUtil.erasure(ret);
+ if (PsiUtil.isRawSubstitutor(method, substitutor)) {
+ final PsiType returnTypeErasure = TypeConversionUtil.erasure(ret);
+ if (Comparing.equal(TypeConversionUtil.erasure(substitutedReturnType), returnTypeErasure)) {
+ return returnTypeErasure;
+ }
+ }
+ PsiType lowerBound = PsiType.NULL;
+ if (substitutedReturnType instanceof PsiCapturedWildcardType) {
+ lowerBound = ((PsiCapturedWildcardType)substitutedReturnType).getLowerBound();
+ } else if (substitutedReturnType instanceof PsiWildcardType) {
+ lowerBound = ((PsiWildcardType)substitutedReturnType).getSuperBound();
+ }
+ if (lowerBound != PsiType.NULL) { //? super
+ final PsiClass containingClass = method.getContainingClass();
+ final PsiExpression qualifierExpression = call.getMethodExpression().getQualifierExpression();
+ final PsiClass childClass = qualifierExpression != null ? PsiUtil.resolveClassInClassTypeOnly(qualifierExpression.getType()) : null;
+ if (containingClass != null && childClass != null) {
+ final PsiType typeInChildClassTypeParams = TypeConversionUtil.getSuperClassSubstitutor(containingClass, childClass, PsiSubstitutor.EMPTY).substitute(ret);
+ final PsiClass substituted = PsiUtil.resolveClassInClassTypeOnly(typeInChildClassTypeParams);
+ if (substituted instanceof PsiTypeParameter) {
+ final PsiClassType[] extendsListTypes = substituted.getExtendsListTypes();
+ if (extendsListTypes.length == 1) {
+ return extendsListTypes[0];
}
}
- return PsiImplUtil.normalizeWildcardTypeByPosition(substitutedReturnType, call);
}
- return TypeConversionUtil.erasure(ret);
}
+ return PsiImplUtil.normalizeWildcardTypeByPosition(substitutedReturnType, call);
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
index 46788578dee6..537ce23c3a77 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
@@ -72,6 +72,15 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
}
@Override
+ public boolean isExact() {
+ PsiElement resolve = resolve();
+ if (resolve instanceof PsiMethod) {
+ return !((PsiMethod)resolve).isVarArgs();
+ }
+ return true;
+ }
+
+ @Override
public PsiExpression getQualifierExpression() {
final PsiElement qualifier = getQualifier();
return qualifier instanceof PsiExpression ? (PsiExpression)qualifier : null;
diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
index 27e4227b5afb..6992e9f5796e 100644
--- a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
+++ b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
@@ -51,15 +51,15 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.scope.conflictResolvers.JavaMethodsConflictResolver");
private final PsiElement myArgumentsList;
- private final PsiType[] myActualParameterTypes;
+ private PsiType[] myActualParameterTypes;
protected LanguageLevel myLanguageLevel;
public JavaMethodsConflictResolver(@NotNull PsiExpressionList list, @NotNull LanguageLevel languageLevel) {
- this(list, list.getExpressionTypes(), languageLevel);
+ this(list, null, languageLevel);
}
public JavaMethodsConflictResolver(@NotNull PsiElement argumentsList,
- @NotNull PsiType[] actualParameterTypes,
+ PsiType[] actualParameterTypes,
@NotNull LanguageLevel languageLevel) {
myArgumentsList = argumentsList;
myActualParameterTypes = actualParameterTypes;
@@ -71,7 +71,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
if (conflicts.isEmpty()) return null;
if (conflicts.size() == 1) return conflicts.get(0);
- boolean atLeastOneMatch = checkParametersNumber(conflicts, myActualParameterTypes.length, true);
+ boolean atLeastOneMatch = checkParametersNumber(conflicts, getActualParameterTypes().length, true);
if (conflicts.size() == 1) return conflicts.get(0);
checkSameSignatures(conflicts);
@@ -80,7 +80,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
checkAccessStaticLevels(conflicts, true);
if (conflicts.size() == 1) return conflicts.get(0);
- checkParametersNumber(conflicts, myActualParameterTypes.length, false);
+ checkParametersNumber(conflicts, getActualParameterTypes().length, false);
if (conflicts.size() == 1) return conflicts.get(0);
final int applicabilityLevel = checkApplicability(conflicts);
@@ -96,7 +96,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
checkSpecifics(conflicts, applicabilityLevel, myLanguageLevel);
if (conflicts.size() == 1) return conflicts.get(0);
- checkPrimitiveVarargs(conflicts, myActualParameterTypes.length);
+ checkPrimitiveVarargs(conflicts, getActualParameterTypes().length);
if (conflicts.size() == 1) return conflicts.get(0);
checkAccessStaticLevels(conflicts, false);
@@ -109,8 +109,8 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
private void checkLambdaApplicable(@NotNull List<CandidateInfo> conflicts, @NotNull LanguageLevel languageLevel) {
if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) return;
- for (int i = 0; i < myActualParameterTypes.length; i++) {
- PsiType parameterType = myActualParameterTypes[i];
+ for (int i = 0; i < getActualParameterTypes().length; i++) {
+ PsiType parameterType = getActualParameterTypes()[i];
if (parameterType instanceof PsiLambdaExpressionType) {
final PsiLambdaExpression lambdaExpression = ((PsiLambdaExpressionType)parameterType).getExpression();
for (Iterator<CandidateInfo> iterator = conflicts.iterator(); iterator.hasNext(); ) {
@@ -122,7 +122,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
if (methodParameters.length == 0) continue;
final PsiParameter param = i < methodParameters.length ? methodParameters[i] : methodParameters[methodParameters.length - 1];
final PsiType paramType = param.getType();
- if (!LambdaUtil.isAcceptable(lambdaExpression, conflict.getSubstitutor().substitute(paramType), true)) {
+ if (!LambdaUtil.isAcceptable(lambdaExpression, conflict.getSubstitutor().substitute(paramType), lambdaExpression.hasFormalParameterTypes())) {
iterator.remove();
} else {
/*todo
@@ -141,7 +141,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
}
}
}
- checkMoreSpecificReturnType(conflicts, myActualParameterTypes, languageLevel);
+ checkMoreSpecificReturnType(conflicts, getActualParameterTypes(), languageLevel);
}
public void checkSpecifics(@NotNull List<CandidateInfo> conflicts,
@@ -426,6 +426,14 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
(method.getCurrentFileResolveScope() instanceof PsiImportStaticStatement ? 0 : 1);
}
+ private PsiType[] getActualParameterTypes() {
+ if (myActualParameterTypes == null) {
+ LOG.assertTrue(myArgumentsList instanceof PsiExpressionList, myArgumentsList);
+ myActualParameterTypes = ((PsiExpressionList)myArgumentsList).getExpressionTypes();
+ }
+ return myActualParameterTypes;
+ }
+
private enum Specifics {
FIRST,
SECOND,
@@ -489,7 +497,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
ProgressManager.checkCanceled();
PsiType type1 = classSubstitutor1.substitute(types1[i]);
PsiType type2 = classSubstitutor2.substitute(types2[i]);
- PsiType argType = i < myActualParameterTypes.length ? myActualParameterTypes[i] : null;
+ PsiType argType = i < getActualParameterTypes().length ? getActualParameterTypes()[i] : null;
boolean boxingInFirst = false;
if (isBoxingHappened(argType, type1, languageLevel)) {
@@ -691,6 +699,12 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
for (int functionalInterfaceIdx = 0; functionalInterfaceIdx < actualParameterTypes.length; functionalInterfaceIdx++) {
final PsiType interfaceReturnType = getReturnType(functionalInterfaceIdx, method);
final PsiType interfaceReturnType1 = getReturnType(functionalInterfaceIdx, conflict);
+ if (actualParameterTypes[functionalInterfaceIdx] instanceof PsiLambdaExpressionType) {
+ final PsiLambdaExpression lambdaExpression = ((PsiLambdaExpressionType)actualParameterTypes[functionalInterfaceIdx]).getExpression();
+ if (!lambdaExpression.hasFormalParameterTypes()) {
+ return Specifics.NEITHER;
+ }
+ }
if (actualParameterTypes[functionalInterfaceIdx] instanceof PsiLambdaExpressionType || actualParameterTypes[functionalInterfaceIdx] instanceof PsiMethodReferenceType) {
if (interfaceReturnType != null && interfaceReturnType1 != null && !Comparing.equal(interfaceReturnType, interfaceReturnType1)) {
Specifics moreSpecific1 = comparePrimitives(actualParameterTypes[functionalInterfaceIdx], interfaceReturnType, interfaceReturnType1);