mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
Generated
+5
@@ -16,5 +16,10 @@
|
||||
<option name="name" value="IntelliJ Dependencies on Bintray" />
|
||||
<option name="url" value="https://jetbrains.bintray.com/intellij-third-party-dependencies" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jcenter"/>
|
||||
<option name="name" value="JCenter on Bintray"/>
|
||||
<option name="url" value="https://jcenter.bintray.com"/>
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
||||
Generated
+4
-4
@@ -1,15 +1,15 @@
|
||||
<component name="libraryTable">
|
||||
<library name="Trove4j">
|
||||
<library name="Trove4j" type="repository">
|
||||
<properties maven-id="org.jetbrains.intellij.deps:trove4j:1.0.20160824" />
|
||||
<ANNOTATIONS>
|
||||
<root url="file://$PROJECT_DIR$/lib/annotations/trove4j" />
|
||||
</ANNOTATIONS>
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/trove4j.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/trove4j/1.0.20160824/trove4j-1.0.20160824.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/src/trove4j_src.jar!/generated/src" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/src/trove4j_src.jar!/core/src" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/trove4j/1.0.20160824/trove4j-1.0.20160824-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
Generated
+4
-3
@@ -1,11 +1,12 @@
|
||||
<component name="libraryTable">
|
||||
<library name="swingx">
|
||||
<library name="swingx" type="repository">
|
||||
<properties maven-id="org.swinglabs:swingx-core:1.6.2-2" />
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/swingx-core-1.6.2.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/swinglabs/swingx-core/1.6.2-2/swingx-core-1.6.2-2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/src/swingx-1.6.2-src.zip!/java"/>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/swinglabs/swingx-core/1.6.2-2/swingx-core-1.6.2-2-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
@@ -1,9 +1,14 @@
|
||||
!define INSTALL_OPTION_ELEMENTS 5
|
||||
!define CUSTOM_SILENT_CONFIG 0
|
||||
|
||||
Function customPreInstallActions
|
||||
DetailPrint "There are no custom pre-install actions."
|
||||
FunctionEnd
|
||||
|
||||
Function customSilentConfigReader
|
||||
DetailPrint "There are no custom silent install actions."
|
||||
FunctionEnd
|
||||
|
||||
Function customInstallActions
|
||||
DetailPrint "There are no custom install actions."
|
||||
FunctionEnd
|
||||
|
||||
+347
-218
@@ -25,11 +25,26 @@ SetCompressor lzma
|
||||
; http://nsis.sourceforge.net/Shortcuts_removal_fails_on_Windows_Vista
|
||||
RequestExecutionLevel user
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Variables
|
||||
;------------------------------------------------------------------------------
|
||||
Var STARTMENU_FOLDER
|
||||
Var config_path
|
||||
Var system_path
|
||||
Var productLauncher
|
||||
Var baseRegKey
|
||||
Var downloadJreX86
|
||||
Var productDir
|
||||
Var control_fields
|
||||
Var max_fields
|
||||
Var silentMode
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; include "Modern User Interface"
|
||||
;------------------------------------------------------------------------------
|
||||
!include "MUI2.nsh"
|
||||
!include "FileFunc.nsh"
|
||||
!include "TextFunc.nsh"
|
||||
!include UAC.nsh
|
||||
!include "InstallOptions.nsh"
|
||||
!include StrFunc.nsh
|
||||
@@ -53,19 +68,6 @@ ReserveFile "DeleteSettings.ini"
|
||||
!define MUI_HEADERIMAGE_BITMAP "${IMAGES_LOCATION}\${PRODUCT_HEADER_FILE}"
|
||||
!define MUI_WELCOMEFINISHPAGE_BITMAP "${IMAGES_LOCATION}\${PRODUCT_LOGO_FILE}"
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Variables
|
||||
;------------------------------------------------------------------------------
|
||||
Var STARTMENU_FOLDER
|
||||
Var config_path
|
||||
Var system_path
|
||||
Var productLauncher
|
||||
Var baseRegKey
|
||||
Var downloadJreX86
|
||||
Var productDir
|
||||
Var control_fields
|
||||
Var max_fields
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; on GUI initialization installer checks whether IDEA is already installed
|
||||
;------------------------------------------------------------------------------
|
||||
@@ -117,92 +119,95 @@ ReserveFile "DeleteSettings.ini"
|
||||
complete:
|
||||
FunctionEnd
|
||||
|
||||
|
||||
Function ${un}SplitStr
|
||||
Exch $0 ; str
|
||||
Push $1 ; inQ
|
||||
Push $3 ; idx
|
||||
Push $4 ; tmp
|
||||
StrCpy $1 0
|
||||
StrCpy $3 0
|
||||
Exch $0 ; str
|
||||
Push $1 ; inQ
|
||||
Push $3 ; idx
|
||||
Push $4 ; tmp
|
||||
StrCpy $1 0
|
||||
StrCpy $3 0
|
||||
loop:
|
||||
StrCpy $4 $0 1 $3
|
||||
${If} $4 == '"'
|
||||
${If} $1 <> 0
|
||||
StrCpy $0 $0 "" 1
|
||||
IntOp $3 $3 - 1
|
||||
${EndIf}
|
||||
IntOp $1 $1 !
|
||||
StrCpy $4 $0 1 $3
|
||||
${If} $4 == '"'
|
||||
${If} $1 <> 0
|
||||
StrCpy $0 $0 "" 1
|
||||
IntOp $3 $3 - 1
|
||||
${EndIf}
|
||||
${If} $4 == '' ; The end?
|
||||
StrCpy $1 0
|
||||
StrCpy $4 ','
|
||||
${EndIf}
|
||||
${If} $4 == ','
|
||||
IntOp $1 $1 !
|
||||
${EndIf}
|
||||
${If} $4 == '' ; The end?
|
||||
StrCpy $1 0
|
||||
StrCpy $4 ','
|
||||
${EndIf}
|
||||
${If} $4 == ','
|
||||
${AndIf} $1 = 0
|
||||
StrCpy $4 $0 $3
|
||||
StrCpy $1 $4 "" -1
|
||||
${IfThen} $1 == '"' ${|} StrCpy $4 $4 -1 ${|}
|
||||
killspace:
|
||||
IntOp $3 $3 + 1
|
||||
StrCpy $0 $0 "" $3
|
||||
StrCpy $1 $0 1
|
||||
StrCpy $3 0
|
||||
StrCmp $1 ',' killspace
|
||||
Push $0 ; Remaining
|
||||
Exch 4
|
||||
Pop $0
|
||||
StrCmp $4 "" 0 moreleft
|
||||
Pop $4
|
||||
Pop $3
|
||||
Pop $1
|
||||
Return
|
||||
moreleft:
|
||||
Exch $4
|
||||
Exch 2
|
||||
Pop $1
|
||||
StrCpy $4 $0 $3
|
||||
StrCpy $1 $4 "" -1
|
||||
${IfThen} $1 == '"' ${|} StrCpy $4 $4 -1 ${|}
|
||||
killspace:
|
||||
IntOp $3 $3 + 1
|
||||
StrCpy $0 $0 "" $3
|
||||
StrCpy $1 $0 1
|
||||
StrCpy $3 0
|
||||
StrCmp $1 ',' killspace
|
||||
Push $0 ; Remaining
|
||||
Exch 4
|
||||
Pop $0
|
||||
StrCmp $4 "" 0 moreleft
|
||||
Pop $4
|
||||
Pop $3
|
||||
Pop $1
|
||||
Return
|
||||
${EndIf}
|
||||
IntOp $3 $3 + 1
|
||||
Goto loop
|
||||
moreleft:
|
||||
Exch $4
|
||||
Exch 2
|
||||
Pop $1
|
||||
Pop $3
|
||||
Return
|
||||
${EndIf}
|
||||
IntOp $3 $3 + 1
|
||||
Goto loop
|
||||
FunctionEnd
|
||||
|
||||
|
||||
!macroend
|
||||
!insertmacro INST_UNINST_SWITCH ""
|
||||
!insertmacro INST_UNINST_SWITCH "un."
|
||||
|
||||
|
||||
Function InstDirState
|
||||
!define InstDirState `!insertmacro InstDirStateCall`
|
||||
!define InstDirState `!insertmacro InstDirStateCall`
|
||||
|
||||
!macro InstDirStateCall _PATH _RESULT
|
||||
Push `${_PATH}`
|
||||
Call InstDirState
|
||||
Pop ${_RESULT}
|
||||
!macroend
|
||||
!macro InstDirStateCall _PATH _RESULT
|
||||
Push `${_PATH}`
|
||||
Call InstDirState
|
||||
Pop ${_RESULT}
|
||||
!macroend
|
||||
|
||||
Exch $0
|
||||
Push $1
|
||||
ClearErrors
|
||||
Exch $0
|
||||
Push $1
|
||||
ClearErrors
|
||||
|
||||
FindFirst $1 $0 '$0\*.*'
|
||||
IfErrors 0 +3
|
||||
StrCpy $0 -1
|
||||
goto end
|
||||
StrCmp $0 '.' 0 +4
|
||||
FindNext $1 $0
|
||||
StrCmp $0 '..' 0 +2
|
||||
FindNext $1 $0
|
||||
FindClose $1
|
||||
IfErrors 0 +3
|
||||
StrCpy $0 0
|
||||
goto end
|
||||
StrCpy $0 1
|
||||
|
||||
end:
|
||||
Pop $1
|
||||
Exch $0
|
||||
FindFirst $1 $0 '$0\*.*'
|
||||
IfErrors 0 +3
|
||||
StrCpy $0 -1
|
||||
goto end
|
||||
StrCmp $0 '.' 0 +4
|
||||
FindNext $1 $0
|
||||
StrCmp $0 '..' 0 +2
|
||||
FindNext $1 $0
|
||||
FindClose $1
|
||||
IfErrors 0 +3
|
||||
StrCpy $0 0
|
||||
goto end
|
||||
StrCpy $0 1
|
||||
end:
|
||||
Pop $1
|
||||
Exch $0
|
||||
FunctionEnd
|
||||
|
||||
|
||||
Function SplitFirstStrPart
|
||||
Exch $R0
|
||||
Exch
|
||||
@@ -212,24 +217,24 @@ Function SplitFirstStrPart
|
||||
StrCpy $R3 $R1
|
||||
StrLen $R1 $R0
|
||||
IntOp $R1 $R1 + 1
|
||||
loop:
|
||||
IntOp $R1 $R1 - 1
|
||||
StrCpy $R2 $R0 1 -$R1
|
||||
StrCmp $R1 0 exit0
|
||||
StrCmp $R2 $R3 exit1 loop
|
||||
exit0:
|
||||
loop:
|
||||
IntOp $R1 $R1 - 1
|
||||
StrCpy $R2 $R0 1 -$R1
|
||||
StrCmp $R1 0 exit0
|
||||
StrCmp $R2 $R3 exit1 loop
|
||||
exit0:
|
||||
StrCpy $R1 ""
|
||||
Goto exit2
|
||||
exit1:
|
||||
IntOp $R1 $R1 - 1
|
||||
StrCmp $R1 0 0 +3
|
||||
exit1:
|
||||
IntOp $R1 $R1 - 1
|
||||
StrCmp $R1 0 0 +3
|
||||
StrCpy $R2 ""
|
||||
Goto +2
|
||||
StrCpy $R2 $R0 "" -$R1
|
||||
IntOp $R1 $R1 + 1
|
||||
StrCpy $R0 $R0 -$R1
|
||||
StrCpy $R1 $R2
|
||||
exit2:
|
||||
StrCpy $R2 $R0 "" -$R1
|
||||
IntOp $R1 $R1 + 1
|
||||
StrCpy $R0 $R0 -$R1
|
||||
StrCpy $R1 $R2
|
||||
exit2:
|
||||
Pop $R3
|
||||
Pop $R2
|
||||
Exch $R1 ;rest
|
||||
@@ -237,29 +242,31 @@ Function SplitFirstStrPart
|
||||
Exch $R0 ;first
|
||||
FunctionEnd
|
||||
|
||||
|
||||
Function VersionSplit
|
||||
!define VersionSplit `!insertmacro VersionSplitCall`
|
||||
!define VersionSplit `!insertmacro VersionSplitCall`
|
||||
|
||||
!macro VersionSplitCall _FULL _PRODUCT _BRANCH _BUILD
|
||||
Push `${_FULL}`
|
||||
Call VersionSplit
|
||||
Pop ${_PRODUCT}
|
||||
Pop ${_BRANCH}
|
||||
Pop ${_BUILD}
|
||||
!macroend
|
||||
!macro VersionSplitCall _FULL _PRODUCT _BRANCH _BUILD
|
||||
Push `${_FULL}`
|
||||
Call VersionSplit
|
||||
Pop ${_PRODUCT}
|
||||
Pop ${_BRANCH}
|
||||
Pop ${_BUILD}
|
||||
!macroend
|
||||
|
||||
Pop $R0
|
||||
Push "-"
|
||||
Push $R0
|
||||
Call SplitFirstStrPart
|
||||
Pop $R0
|
||||
Pop $R1
|
||||
Push "."
|
||||
Push $R1
|
||||
Call SplitFirstStrPart
|
||||
Push $R0
|
||||
Pop $R0
|
||||
Push "-"
|
||||
Push $R0
|
||||
Call SplitFirstStrPart
|
||||
Pop $R0
|
||||
Pop $R1
|
||||
Push "."
|
||||
Push $R1
|
||||
Call SplitFirstStrPart
|
||||
Push $R0
|
||||
FunctionEnd
|
||||
|
||||
|
||||
Function OnDirectoryPageLeave
|
||||
;check
|
||||
; - if there are no files into $INSTDIR (recursively)
|
||||
@@ -281,18 +288,18 @@ Function instDirEmpty
|
||||
ClearErrors
|
||||
FindFirst $1 $2 "$9\*.*"
|
||||
IfErrors done 0
|
||||
nextElemement:
|
||||
next_elemement:
|
||||
;is the element a folder?
|
||||
StrCmp $2 "." getNextElement
|
||||
StrCmp $2 ".." getNextElement
|
||||
IfFileExists "$9\$2\*.*" 0 nextFile
|
||||
StrCmp $2 "." get_next_element
|
||||
StrCmp $2 ".." get_next_element
|
||||
IfFileExists "$9\$2\*.*" 0 next_file
|
||||
Push $9
|
||||
StrCpy "$9" "$9\$2"
|
||||
Call instDirEmpty
|
||||
StrCmp $9 "not empty" done 0
|
||||
Pop $9
|
||||
Goto getNextElement
|
||||
nextFile:
|
||||
Goto get_next_element
|
||||
next_file:
|
||||
;is it the file property?
|
||||
${If} $2 != "idea.properties"
|
||||
${AndIf} $2 != "${PRODUCT_EXE_FILE}.vmoptions"
|
||||
@@ -301,9 +308,9 @@ nextFile:
|
||||
StrCpy $9 "not empty"
|
||||
Goto done
|
||||
${EndIf}
|
||||
getNextElement:
|
||||
get_next_element:
|
||||
FindNext $1 $2
|
||||
IfErrors 0 nextElemement
|
||||
IfErrors 0 next_elemement
|
||||
done:
|
||||
FindClose $1
|
||||
Pop $2
|
||||
@@ -311,19 +318,6 @@ done:
|
||||
Pop $0
|
||||
FunctionEnd
|
||||
|
||||
Function searchJava64
|
||||
StrCpy $0 "HKLM"
|
||||
StrCpy $1 "Software\JavaSoft\Java Development Kit\${JAVA_REQUIREMENT}"
|
||||
StrCpy $2 "JavaHome"
|
||||
SetRegView 64
|
||||
call OMReadRegStr
|
||||
SetRegView 32
|
||||
StrCpy $3 "$3\bin\java.exe"
|
||||
IfFileExists $3 done no_java_64
|
||||
no_java_64:
|
||||
StrCpy $3 ""
|
||||
done:
|
||||
FunctionEnd
|
||||
|
||||
Function ConfirmDesktopShortcut
|
||||
!insertmacro MUI_HEADER_TEXT "$(installation_options)" "$(installation_options_prompt)"
|
||||
@@ -344,7 +338,7 @@ Function ConfirmDesktopShortcut
|
||||
${EndIf}
|
||||
|
||||
; if jre x86 for the build is available then add checkbox to Installation Options dialog
|
||||
StrCmp "${LINK_TO_JRE}" "null" customPreActions 0
|
||||
StrCmp "${LINK_TO_JRE}" "null" custom_pre_actions 0
|
||||
inetc::head /SILENT /TOSTACK ${LINK_TO_JRE} "" /END
|
||||
Pop $0
|
||||
${If} $0 == "OK"
|
||||
@@ -358,7 +352,7 @@ Function ConfirmDesktopShortcut
|
||||
!insertmacro INSTALLOPTIONS_WRITE "Desktop.ini" "Field 4" "State" $downloadJreX86
|
||||
!insertmacro INSTALLOPTIONS_WRITE "Desktop.ini" "Field 4" "Text" "Download and install JRE x86 by JetBrains"
|
||||
${EndIf}
|
||||
customPreActions:
|
||||
custom_pre_actions:
|
||||
Call customPreInstallActions
|
||||
SetRegView 32
|
||||
StrCmp "${ASSOCIATION}" "NoAssociation" skip_association
|
||||
@@ -378,6 +372,7 @@ done:
|
||||
!insertmacro INSTALLOPTIONS_DISPLAY "Desktop.ini"
|
||||
FunctionEnd
|
||||
|
||||
|
||||
Function downloadJre
|
||||
!insertmacro INSTALLOPTIONS_READ $R0 "Desktop.ini" "Field 4" "State"
|
||||
${If} $R0 == 1
|
||||
@@ -385,10 +380,10 @@ Function downloadJre
|
||||
Pop $0
|
||||
${If} $0 == "OK"
|
||||
untgz::extract "-d" "$INSTDIR\jre32" "$TEMP\jre.tar.gz"
|
||||
StrCmp $R0 "success" removeTempJre
|
||||
StrCmp $R0 "success" remove_temp_jre
|
||||
DetailPrint "Failed to extract jre.tar.gz"
|
||||
MessageBox MB_OK|MB_ICONEXCLAMATION|MB_DEFBUTTON1 "Failed to extract $TEMP\jre.tar.gz"
|
||||
removeTempJre:
|
||||
remove_temp_jre:
|
||||
IfFileExists "$TEMP\jre.tar.gz" 0 done
|
||||
Delete "$TEMP\jre.tar.gz"
|
||||
${Else}
|
||||
@@ -398,13 +393,11 @@ removeTempJre:
|
||||
done:
|
||||
FunctionEnd
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; configuration
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
|
||||
Page custom uninstallOldVersionDialog
|
||||
|
||||
!ifdef LICENSE_FILE
|
||||
@@ -458,51 +451,112 @@ LicenseLangString myLicenseData ${LANG_ENGLISH} "${LICENSE_FILE}.txt"
|
||||
LicenseLangString myLicenseData ${LANG_JAPANESE} "${LICENSE_FILE}.txt"
|
||||
!endif
|
||||
|
||||
|
||||
Function .onInit
|
||||
SetRegView 32
|
||||
!insertmacro INSTALLOPTIONS_EXTRACT "Desktop.ini"
|
||||
IfSilent silent_mode uac_elevate
|
||||
silent_mode:
|
||||
IntCmp ${CUSTOM_SILENT_CONFIG} 0 silent_config silent_config custom_silent_config
|
||||
silent_config:
|
||||
Call silentConfigReader
|
||||
Goto set_reg_key
|
||||
custom_silent_config:
|
||||
Call customSilentConfigReader
|
||||
set_reg_key:
|
||||
StrCpy $baseRegKey "HKCU"
|
||||
IfSilent UAC_Done
|
||||
UAC_Elevate:
|
||||
!insertmacro UAC_RunElevated
|
||||
StrCmp 1223 $0 UAC_ElevationAborted ; UAC dialog aborted by user? - continue install under user
|
||||
StrCmp 0 $0 0 UAC_Err ; Error?
|
||||
StrCmp 1 $1 0 UAC_Success ;Are we the real deal or just the wrapper?
|
||||
Quit
|
||||
UAC_Err:
|
||||
Abort
|
||||
UAC_ElevationAborted:
|
||||
StrCpy $INSTDIR "$APPDATA\${MANUFACTURER}\${PRODUCT_WITH_VER}"
|
||||
goto UAC_Done
|
||||
UAC_Success:
|
||||
StrCmp 1 $3 UAC_Admin ;Admin?
|
||||
StrCmp 3 $1 0 UAC_ElevationAborted ;Try again?
|
||||
goto UAC_Elevate
|
||||
UAC_Admin:
|
||||
${If} ${RunningX64}
|
||||
StrCpy $INSTDIR "$PROGRAMFILES64\${MANUFACTURER}\${PRODUCT_WITH_VER}"
|
||||
${Else}
|
||||
StrCpy $INSTDIR "$PROGRAMFILES\${MANUFACTURER}\${PRODUCT_WITH_VER}"
|
||||
${EndIf}
|
||||
SetShellVarContext all
|
||||
StrCpy $baseRegKey "HKLM"
|
||||
UAC_Done:
|
||||
StrCmp $silentMode "admin" uac_elevate done
|
||||
uac_elevate:
|
||||
!insertmacro UAC_RunElevated
|
||||
StrCmp 1223 $0 uac_elevation_aborted ; UAC dialog aborted by user? - continue install under user
|
||||
StrCmp 0 $0 0 uac_err ; Error?
|
||||
StrCmp 1 $1 0 uac_success ;Are we the real deal or just the wrapper?
|
||||
Quit
|
||||
uac_err:
|
||||
Abort
|
||||
uac_elevation_aborted:
|
||||
IfSilent done set_install_dir
|
||||
set_install_dir:
|
||||
StrCpy $INSTDIR "$APPDATA\${MANUFACTURER}\${PRODUCT_WITH_VER}"
|
||||
goto done
|
||||
uac_success:
|
||||
StrCmp 1 $3 uac_admin ;Admin?
|
||||
StrCmp 3 $1 0 uac_elevation_aborted ;Try again?
|
||||
goto uac_elevate
|
||||
uac_admin:
|
||||
IfSilent uac_all_users set_install_dir_admin_mode
|
||||
set_install_dir_admin_mode:
|
||||
${If} ${RunningX64}
|
||||
StrCpy $INSTDIR "$PROGRAMFILES64\${MANUFACTURER}\${PRODUCT_WITH_VER}"
|
||||
${Else}
|
||||
StrCpy $INSTDIR "$PROGRAMFILES\${MANUFACTURER}\${PRODUCT_WITH_VER}"
|
||||
${EndIf}
|
||||
uac_all_users:
|
||||
SetShellVarContext all
|
||||
StrCpy $baseRegKey "HKLM"
|
||||
done:
|
||||
; !insertmacro MUI_LANGDLL_DISPLAY
|
||||
FunctionEnd
|
||||
|
||||
|
||||
Function silentConfigReader
|
||||
${GetParameters} $R0
|
||||
ClearErrors
|
||||
|
||||
${GetOptions} $R0 /CONFIG= $R1
|
||||
IfErrors no_silent_config
|
||||
|
||||
${ConfigRead} "$R1" "mode=" $R0
|
||||
StrCpy $silentMode "user"
|
||||
IfErrors launcher_32
|
||||
StrCpy $silentMode $R0
|
||||
|
||||
launcher_32:
|
||||
ClearErrors
|
||||
${ConfigRead} "$R1" "launcher32=" $R3
|
||||
IfErrors launcher_64
|
||||
!insertmacro INSTALLOPTIONS_WRITE "Desktop.ini" "Field 2" "State" $R3
|
||||
|
||||
launcher_64:
|
||||
ClearErrors
|
||||
${ConfigRead} "$R1" "launcher64=" $R3
|
||||
IfErrors download_jre32
|
||||
!insertmacro INSTALLOPTIONS_WRITE "Desktop.ini" "Field 3" "Type" "checkbox"
|
||||
!insertmacro INSTALLOPTIONS_WRITE "Desktop.ini" "Field 3" "State" $R3
|
||||
|
||||
download_jre32:
|
||||
ClearErrors
|
||||
${ConfigRead} "$R1" "jre32=" $R3
|
||||
IfErrors associations
|
||||
!insertmacro INSTALLOPTIONS_WRITE "Desktop.ini" "Field 4" "Type" "checkbox"
|
||||
!insertmacro INSTALLOPTIONS_WRITE "Desktop.ini" "Field 4" "State" $R3
|
||||
|
||||
associations:
|
||||
ClearErrors
|
||||
StrCmp "${ASSOCIATION}" "NoAssociation" done
|
||||
!insertmacro INSTALLOPTIONS_READ $R0 "Desktop.ini" "Settings" "NumFields"
|
||||
push "${ASSOCIATION}"
|
||||
loop:
|
||||
call SplitStr
|
||||
Pop $0
|
||||
StrCmp $0 "" update_settings
|
||||
ClearErrors
|
||||
${ConfigRead} "$R1" "$0=" $R3
|
||||
IfErrors update_settings
|
||||
IntOp $R0 $R0 + 1
|
||||
!insertmacro INSTALLOPTIONS_WRITE "Desktop.ini" "Field $R0" "State" $R3
|
||||
!insertmacro INSTALLOPTIONS_WRITE "Desktop.ini" "Field $R0" "Text" "$0"
|
||||
goto loop
|
||||
|
||||
update_settings:
|
||||
!insertmacro INSTALLOPTIONS_WRITE "Desktop.ini" "Settings" "NumFields" "$R0"
|
||||
no_silent_config:
|
||||
done:
|
||||
FunctionEnd
|
||||
|
||||
Function checkVersion
|
||||
StrCpy $2 ""
|
||||
StrCpy $1 "Software\${MANUFACTURER}\${PRODUCT_REG_VER}"
|
||||
; ${If} $0 == "HKLM"
|
||||
; StrCpy $1 "Software\${MANUFACTURER}\${PRODUCT_REG_VER}"
|
||||
; Push $0
|
||||
; call winVersion
|
||||
; ${If} $0 == "1"
|
||||
; StrCpy $1 "Software\Wow6432Node\${MANUFACTURER}\${PRODUCT_REG_VER}"
|
||||
; ${Else}
|
||||
; StrCpy $1 "Software\${MANUFACTURER}\${PRODUCT_REG_VER}"
|
||||
; ${EndIf}
|
||||
; Pop $0
|
||||
; ${EndIf}
|
||||
Call OMReadRegStr
|
||||
IfFileExists $3\bin\${PRODUCT_EXE_FILE} check_version
|
||||
Goto Done
|
||||
@@ -533,7 +587,7 @@ FunctionEnd
|
||||
|
||||
|
||||
Function uninstallOldVersion
|
||||
; uninstallation mode
|
||||
;uninstallation mode
|
||||
!insertmacro INSTALLOPTIONS_READ $9 "UninstallOldVersions.ini" "Field 2" "State"
|
||||
${If} $9 == "1"
|
||||
ExecWait '"$3\bin\Uninstall.exe" /S'
|
||||
@@ -544,7 +598,7 @@ Function uninstallOldVersion
|
||||
goto complete
|
||||
uninstall:
|
||||
;previous installation has been removed
|
||||
;customer decided to keep properties?
|
||||
;customer has decided to keep properties?
|
||||
IfFileExists $3\bin\idea.properties saveProperties fullRemove
|
||||
saveProperties:
|
||||
Delete "$3\bin\Uninstall.exe"
|
||||
@@ -563,12 +617,12 @@ StrCpy $6 ""
|
||||
loop:
|
||||
IntOp $7 $7 + 1
|
||||
${If} $8 >= $7
|
||||
!insertmacro INSTALLOPTIONS_READ $6 "UninstallOldVersions.ini" "Field $7" "Text"
|
||||
${If} $6 == $3
|
||||
;found the same value in list of installations
|
||||
StrCpy $6 "duplicated"
|
||||
Goto finish
|
||||
${EndIf}
|
||||
!insertmacro INSTALLOPTIONS_READ $6 "UninstallOldVersions.ini" "Field $7" "Text"
|
||||
${If} $6 == $3
|
||||
;found the same value in list of installations
|
||||
StrCpy $6 "duplicated"
|
||||
Goto finish
|
||||
${EndIf}
|
||||
Goto loop
|
||||
${EndIf}
|
||||
finish:
|
||||
@@ -609,6 +663,7 @@ ${If} $0 == "HKLM"
|
||||
StrCpy $4 0
|
||||
Goto get_installation_info
|
||||
${EndIf}
|
||||
|
||||
complete:
|
||||
!insertmacro INSTALLOPTIONS_WRITE "UninstallOldVersions.ini" "Settings" "NumFields" "$8"
|
||||
${If} $8 > $control_fields
|
||||
@@ -710,7 +765,6 @@ continue_enum_versions_hkcu:
|
||||
Goto enum_versions_hkcu
|
||||
|
||||
end_enum_versions_hkcu:
|
||||
|
||||
StrCpy $0 "0" # registry key index
|
||||
|
||||
enum_versions_hklm:
|
||||
@@ -725,15 +779,14 @@ continue_enum_versions_hklm:
|
||||
Goto enum_versions_hklm
|
||||
|
||||
end_enum_versions_hklm:
|
||||
|
||||
StrCmp $INSTDIR "" 0 skip_default_instdir
|
||||
${If} ${RunningX64}
|
||||
StrCpy $INSTDIR "$PROGRAMFILES64\${MANUFACTURER}\${MUI_PRODUCT} ${MUI_VERSION_MAJOR}.${MUI_VERSION_MINOR}"
|
||||
${Else}
|
||||
StrCpy $INSTDIR "$PROGRAMFILES\${MANUFACTURER}\${MUI_PRODUCT} ${MUI_VERSION_MAJOR}.${MUI_VERSION_MINOR}"
|
||||
${EndIf}
|
||||
skip_default_instdir:
|
||||
|
||||
skip_default_instdir:
|
||||
Pop $5
|
||||
Pop $4
|
||||
Pop $3
|
||||
@@ -763,22 +816,60 @@ createRegistration:
|
||||
FunctionEnd
|
||||
|
||||
Function ProductAssociation
|
||||
push $0
|
||||
push $1
|
||||
push $2
|
||||
push $3
|
||||
StrCpy $2 ""
|
||||
StrCmp $baseRegKey "HKLM" admin user
|
||||
admin:
|
||||
StrCpy $0 HKCR
|
||||
StrCpy $R5 ${PRODUCT_PATHS_SELECTOR}
|
||||
goto back_up
|
||||
user:
|
||||
StrCpy $0 HKCU
|
||||
StrCpy $R4 "Software\Classes\$R4"
|
||||
StrCpy $R5 "Software\Classes\${PRODUCT_PATHS_SELECTOR}"
|
||||
back_up:
|
||||
; back up old value of an association
|
||||
ReadRegStr $1 HKCR $R4 ""
|
||||
StrCmp $1 "" skip_backup
|
||||
StrCmp $1 ${PRODUCT_PATHS_SELECTOR} skip_backup
|
||||
WriteRegStr HKCR $R4 "backup_val" $1
|
||||
StrCpy $1 $R4
|
||||
call OMReadRegStr
|
||||
StrCmp $3 "" skip_backup
|
||||
StrCmp $3 ${PRODUCT_PATHS_SELECTOR} skip_backup
|
||||
StrCpy $2 "backup_val"
|
||||
Call OMWriteRegStr
|
||||
skip_backup:
|
||||
WriteRegStr HKCR $R4 "" "${PRODUCT_PATHS_SELECTOR}"
|
||||
ReadRegStr $0 HKCR ${PRODUCT_PATHS_SELECTOR} ""
|
||||
StrCmp $0 "" 0 command_exists
|
||||
WriteRegStr HKCR ${PRODUCT_PATHS_SELECTOR} "" "${PRODUCT_FULL_NAME}"
|
||||
WriteRegStr HKCR "${PRODUCT_PATHS_SELECTOR}\shell" "" "open"
|
||||
WriteRegStr HKCR "${PRODUCT_PATHS_SELECTOR}\DefaultIcon" "" "$productLauncher,0"
|
||||
StrCpy $2 ""
|
||||
StrCpy $3 ${PRODUCT_PATHS_SELECTOR}
|
||||
Call OMWriteRegStr
|
||||
StrCpy $1 $R5
|
||||
StrCpy $2 ""
|
||||
Call OMReadRegStr
|
||||
StrCmp $3 "" 0 command_exists
|
||||
StrCpy $2 ""
|
||||
StrCpy $3 "${PRODUCT_FULL_NAME}"
|
||||
Call OMWriteRegStr
|
||||
StrCpy $1 "$R5\shell"
|
||||
StrCpy $2 ""
|
||||
StrCpy $3 "open"
|
||||
Call OMWriteRegStr
|
||||
StrCpy $1 "$R5\DefaultIcon"
|
||||
StrCpy $2 ""
|
||||
StrCpy $3 "$productLauncher,0"
|
||||
Call OMWriteRegStr
|
||||
command_exists:
|
||||
WriteRegStr HKCR "${PRODUCT_PATHS_SELECTOR}\DefaultIcon" "" " $productLauncher,0"
|
||||
WriteRegStr HKCR "${PRODUCT_PATHS_SELECTOR}\shell\open\command" "" \
|
||||
'"$productLauncher" "%1"'
|
||||
StrCpy $1 "$R5\DefaultIcon"
|
||||
StrCpy $2 ""
|
||||
StrCpy $3 " $productLauncher,0"
|
||||
Call OMWriteRegStr
|
||||
StrCpy $1 "$R5\shell\open\command"
|
||||
StrCpy $2 ""
|
||||
StrCpy $3 '"$productLauncher" "%1"'
|
||||
Call OMWriteRegStr
|
||||
pop $3
|
||||
pop $2
|
||||
pop $1
|
||||
pop $0
|
||||
FunctionEnd
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
@@ -786,20 +877,22 @@ FunctionEnd
|
||||
;------------------------------------------------------------------------------
|
||||
Section "IDEA Files" CopyIdeaFiles
|
||||
CreateDirectory $INSTDIR
|
||||
Call customInstallActions
|
||||
SetRegView 32
|
||||
|
||||
; set up a launcher for associations
|
||||
;define launcher in accordingly to OS version
|
||||
${If} ${RunningX64}
|
||||
StrCpy $productLauncher "$INSTDIR\bin\${PRODUCT_EXE_FILE_64}"
|
||||
${Else}
|
||||
StrCpy $productLauncher "$INSTDIR\bin\${PRODUCT_EXE_FILE}"
|
||||
${EndIf}
|
||||
DetailPrint "productLauncher: $productLauncher"
|
||||
|
||||
StrCmp "${LINK_TO_JRE}" "null" shortcuts 0
|
||||
; download and install JRE x86
|
||||
;download and install JRE x86
|
||||
Call downloadJre
|
||||
|
||||
shortcuts:
|
||||
; create shortcuts
|
||||
!insertmacro INSTALLOPTIONS_READ $R2 "Desktop.ini" "Field 2" "State"
|
||||
StrCmp $R2 1 "" exe_64
|
||||
CreateShortCut "$DESKTOP\${PRODUCT_FULL_NAME_WITH_VER}.lnk" \
|
||||
@@ -823,11 +916,7 @@ get_user_choice:
|
||||
next_association:
|
||||
IntOp $R2 $R2 + 1
|
||||
IntCmp $R1 $R2 get_user_choice done get_user_choice
|
||||
|
||||
done:
|
||||
Call customInstallActions
|
||||
SetRegView 32
|
||||
|
||||
; registration application to be presented in Open With list
|
||||
call ProductRegistration
|
||||
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
|
||||
@@ -867,10 +956,9 @@ done:
|
||||
!undef Index
|
||||
|
||||
skip_ipr:
|
||||
|
||||
; readonly section
|
||||
SectionIn RO
|
||||
!include "idea_win.nsh"
|
||||
!include "idea_win.nsh"
|
||||
|
||||
SetOutPath $INSTDIR\bin
|
||||
File "${PRODUCT_PROPERTIES_FILE}"
|
||||
@@ -1012,16 +1100,44 @@ UAC_Done:
|
||||
FunctionEnd
|
||||
|
||||
|
||||
Function un.ReturnBackupRegValue
|
||||
Function un.RestoreBackupRegValue
|
||||
;replace Default str with the backup value (if there is the one) and then delete backup
|
||||
; $1 - key (for example ".java")
|
||||
; $2 - name (for example "backup_val")
|
||||
Push $0
|
||||
ReadRegStr $0 HKCR $1 $2
|
||||
StrCmp $0 "" "noBackup"
|
||||
WriteRegStr HKCR $1 "" $0
|
||||
DeleteRegValue HKCR $1 $2
|
||||
noBackup:
|
||||
Push $3
|
||||
|
||||
StrCmp $baseRegKey "HKLM" admin user
|
||||
admin:
|
||||
StrCpy $0 HKCR
|
||||
goto read_backup_value
|
||||
user:
|
||||
StrCpy $0 HKCU
|
||||
StrCpy $1 "Software\Classes\$1"
|
||||
|
||||
read_backup_value:
|
||||
call un.OMReadRegStr
|
||||
StrCmp $3 "" no_backup restore_backup
|
||||
|
||||
no_backup:
|
||||
;clean default value if it contains current product info
|
||||
StrCpy $2 ""
|
||||
call un.OMReadRegStr
|
||||
StrCmp $4 $3 0 done
|
||||
call un.OMDeleteRegValue
|
||||
goto done
|
||||
|
||||
restore_backup:
|
||||
StrCmp $3 $4 remove_backup 0
|
||||
push $2
|
||||
StrCpy $2 ""
|
||||
call un.OMWriteRegStr
|
||||
pop $2
|
||||
remove_backup:
|
||||
call un.OMDeleteRegValue
|
||||
|
||||
done:
|
||||
Pop $3
|
||||
Pop $0
|
||||
FunctionEnd
|
||||
|
||||
@@ -1225,7 +1341,7 @@ skip_delete_settings:
|
||||
StrCmp $R9 "" registry
|
||||
StrCpy $5 "Software\${MANUFACTURER}"
|
||||
shortcuts:
|
||||
;the user has the admin rights
|
||||
;user has the admin rights
|
||||
IfFileExists "$DESKTOP\${PRODUCT_FULL_NAME_WITH_VER}.lnk" keep_current_user
|
||||
SetShellVarContext all
|
||||
keep_current_user:
|
||||
@@ -1244,13 +1360,17 @@ registry:
|
||||
StrCmp "${ASSOCIATION}" "NoAssociation" finish_uninstall
|
||||
push "${ASSOCIATION}"
|
||||
loop:
|
||||
StrCpy $2 "backup_val"
|
||||
StrCpy $4 "${PRODUCT_PATHS_SELECTOR}"
|
||||
call un.SplitStr
|
||||
Pop $0
|
||||
StrCmp $0 "" finish_uninstall
|
||||
|
||||
;restore backup association(s)
|
||||
StrCpy $1 $0
|
||||
StrCpy $2 "backup_val"
|
||||
Call un.ReturnBackupRegValue
|
||||
Call un.RestoreBackupRegValue
|
||||
goto loop
|
||||
|
||||
finish_uninstall:
|
||||
StrCpy $0 $baseRegKey
|
||||
StrCpy $1 "$5\${PRODUCT_REG_VER}"
|
||||
@@ -1275,8 +1395,16 @@ finish:
|
||||
StrCpy $0 "HKCR"
|
||||
StrCpy $1 "Applications\${PRODUCT_EXE_FILE}"
|
||||
Call un.OMDeleteRegKey
|
||||
StrCmp $baseRegKey "HKLM" admin user
|
||||
admin:
|
||||
StrCpy $0 "HKCR"
|
||||
StrCpy $1 "${PRODUCT_PATHS_SELECTOR}"
|
||||
goto delete_association
|
||||
user:
|
||||
StrCpy $0 "HKCU"
|
||||
StrCpy $1 "Software\Classes\${PRODUCT_PATHS_SELECTOR}"
|
||||
delete_association:
|
||||
; remove product information which was used for association(s)
|
||||
Call un.OMDeleteRegKey
|
||||
|
||||
StrCpy $0 "${MUI_LANGDLL_REGISTRY_ROOT}"
|
||||
@@ -1287,6 +1415,7 @@ finish:
|
||||
StrCpy $1 "IntelliJIdeaProjectFile\DefaultIcon"
|
||||
StrCpy $2 ""
|
||||
call un.OMReadRegStr
|
||||
|
||||
StrCmp $3 "$productDir\${PRODUCT_EXE_FILE},0" remove_IntelliJIdeaProjectFile done
|
||||
remove_IntelliJIdeaProjectFile:
|
||||
StrCpy $1 "IntelliJIdeaProjectFile"
|
||||
|
||||
@@ -81,8 +81,6 @@ Function ${un}OMReadRegStr
|
||||
hkcr:
|
||||
ReadRegStr $3 HKCR $1 $2
|
||||
done:
|
||||
IfErrors 0 +2
|
||||
DetailPrint "ERROR: $0, $1, $2"
|
||||
FunctionEnd
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
|
||||
@@ -116,6 +116,5 @@ task dependenciesFile() {
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
// 2.14 is the latest version supports Java 6 (which is still present on TeamCity build agents)
|
||||
gradleVersion = '2.14'
|
||||
gradleVersion = '4.3.1'
|
||||
}
|
||||
Binary file not shown.
@@ -1,6 +1,5 @@
|
||||
#Fri Feb 17 14:30:05 MSK 2017
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.3.1-bin.zip
|
||||
|
||||
Vendored
+3
-3
@@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS=""
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
@@ -155,7 +155,7 @@ if $cygwin ; then
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save ( ) {
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url "http://repo.labs.intellij.net/intellij-third-party-dependencies/" }
|
||||
maven { url "https://jetbrains.bintray.com/intellij-third-party-dependencies" }
|
||||
}
|
||||
|
||||
configurations {
|
||||
@@ -28,6 +30,7 @@ dependencies {
|
||||
buildScriptsDeps loadLibraryMavenId("OroMatcher")
|
||||
buildScriptsDeps loadLibraryMavenId("commons-codec")
|
||||
buildScriptsDeps loadLibraryMavenId("commons-logging")
|
||||
buildScriptsDeps loadLibraryMavenId("Trove4j")
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
<fileset dir="${idea.lib}">
|
||||
<include name="jdom.jar"/>
|
||||
<include name="log4j.jar"/>
|
||||
<include name="trove4j.jar"/>
|
||||
<include name="netty*.jar"/>
|
||||
<include name="asm-all.jar"/>
|
||||
<include name="jgoodies-forms.jar"/>
|
||||
|
||||
@@ -55,7 +55,6 @@ abstract class BaseIdeaProperties extends ProductProperties {
|
||||
productLayout.additionalPlatformJars.put("jps-builders-6.jar", "jps-builders-6")
|
||||
productLayout.additionalPlatformJars.put("aether-dependency-resolver.jar", "aether-dependency-resolver")
|
||||
productLayout.additionalPlatformJars.put("jshell-protocol.jar", "jshell-protocol")
|
||||
productLayout.additionalPlatformJars.putAll("jps-model.jar", ["jps-model-impl", "jps-model-serialization"])
|
||||
productLayout.additionalPlatformJars.putAll("resources.jar", ["resources", "resources-en"])
|
||||
productLayout.additionalPlatformJars.
|
||||
putAll("javac2.jar", ["javac2", "forms-compiler", "forms_rt", "instrumentation-util", "instrumentation-util-8", "javac-ref-scanner-8"])
|
||||
|
||||
@@ -33,8 +33,7 @@ class IdeaCommunityProperties extends BaseIdeaProperties {
|
||||
buildCrossPlatformDistribution = true
|
||||
|
||||
productLayout.platformApiJarModules = CommunityRepositoryModules.PLATFORM_API_MODULES
|
||||
//jps modules are packed into a separate JAR to include into build process's classpath so we need to exclude them from the main platform JAR
|
||||
productLayout.platformImplJarModules = CommunityRepositoryModules.PLATFORM_IMPLEMENTATION_MODULES - ["jps-model-impl", "jps-model-serialization"]
|
||||
productLayout.platformImplJarModules = CommunityRepositoryModules.PLATFORM_IMPLEMENTATION_MODULES
|
||||
productLayout.productApiModules = JAVA_API_MODULES
|
||||
productLayout.productImplementationModules = JAVA_IMPLEMENTATION_MODULES +
|
||||
["duplicates-analysis", "structuralsearch", "structuralsearch-java", "typeMigration", "platform-main"]
|
||||
|
||||
@@ -154,17 +154,23 @@ private boolean ensureKotlinCompilerAddedToClassPath() {
|
||||
return true
|
||||
}
|
||||
|
||||
def kotlinPluginLibPath = "$home/build/dependencies/build/kotlin/Kotlin/lib"
|
||||
if (!new File(kotlinPluginLibPath).exists()) {
|
||||
kotlinPluginLibPath = "$home/community/build/dependencies/build/kotlin/Kotlin/lib"
|
||||
def kotlinHomePath = "$home/build/dependencies/build/kotlin/Kotlin"
|
||||
if (!new File(kotlinHomePath).exists()) {
|
||||
kotlinHomePath = "$home/community/build/dependencies/build/kotlin/Kotlin"
|
||||
}
|
||||
if (!new File(kotlinPluginLibPath, "kotlin-runtime.jar").exists()) {
|
||||
projectBuilder.error("Could not find Kotlin JARs at $kotlinPluginLibPath: run `./gradlew setupKotlinPlugin` in dependencies module " +
|
||||
"to download Kotlin JARs")
|
||||
return false
|
||||
def kotlinPluginLibPath = "$kotlinHomePath/lib"
|
||||
def kotlincLibPath = "$kotlinHomePath/kotlinc/lib"
|
||||
if (new File(kotlinPluginLibPath).exists() && new File(kotlincLibPath).exists()) {
|
||||
["jps/kotlin-jps-plugin.jar", "kotlin-plugin.jar", "kotlin-reflect.jar"].each {
|
||||
BuildUtils.addToJpsClassPath("$kotlinPluginLibPath/$it", ant)
|
||||
}
|
||||
["kotlin-runtime.jar"].each {
|
||||
BuildUtils.addToJpsClassPath("$kotlincLibPath/$it", ant)
|
||||
}
|
||||
}
|
||||
["jps/kotlin-jps-plugin.jar", "kotlin-plugin.jar", "kotlin-runtime.jar", "kotlin-reflect.jar"].each {
|
||||
BuildUtils.addToJpsClassPath("$kotlinPluginLibPath/$it", ant)
|
||||
else {
|
||||
projectBuilder.error(
|
||||
"Could not find Kotlin JARs at $kotlinPluginLibPath and $kotlincLibPath: run `./gradlew setupKotlinPlugin` in dependencies module to download Kotlin JARs")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
package com.intellij.build;
|
||||
|
||||
import com.intellij.build.events.*;
|
||||
import com.intellij.build.events.impl.FailureImpl;
|
||||
import com.intellij.execution.ExecutionBundle;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
@@ -134,16 +134,15 @@ public abstract class AbstractViewManager implements ViewManager, BuildProgressL
|
||||
if (buildInfo.result instanceof FailureResult) {
|
||||
boolean activate = buildInfo.activateToolWindowWhenFailed;
|
||||
myBuildContentManager.setSelectedContent(buildInfo.content, activate, activate, activate, null);
|
||||
List<? extends Failure> failures = ((FailureResult)buildInfo.result).getFailures();
|
||||
List<? extends Failure>
|
||||
failures = ((FailureResult)buildInfo.result).getFailures();
|
||||
if (failures.isEmpty()) return;
|
||||
Failure failure = failures.get(0);
|
||||
if (failure instanceof FailureImpl) {
|
||||
NotificationData notificationData = ((FailureImpl)failure).getNotificationData();
|
||||
if (notificationData != null) {
|
||||
final String title = notificationData.getNotification().getTitle();
|
||||
final String content = notificationData.getNotification().getContent();
|
||||
SystemNotifications.getInstance().notify(ToolWindowId.BUILD, title, content);
|
||||
}
|
||||
Notification notification = failure.getNotification();
|
||||
if (notification != null) {
|
||||
final String title = notification.getTitle();
|
||||
final String content = notification.getContent();
|
||||
SystemNotifications.getInstance().notify(ToolWindowId.BUILD, title, content);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,7 +195,7 @@ public abstract class AbstractViewManager implements ViewManager, BuildProgressL
|
||||
String tabName = getPinnedTabName(buildsView);
|
||||
UIUtil.invokeLaterIfNeeded(() -> {
|
||||
content.setPinnable(false);
|
||||
if(content.getIcon() == null) {
|
||||
if (content.getIcon() == null) {
|
||||
content.setIcon(EmptyIcon.ICON_8);
|
||||
}
|
||||
content.putUserData(ToolWindow.SHOW_CONTENT_ICON, Boolean.TRUE);
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.intellij.build;
|
||||
|
||||
import com.intellij.build.events.*;
|
||||
import com.intellij.build.events.impl.FailureImpl;
|
||||
import com.intellij.execution.filters.Filter;
|
||||
import com.intellij.execution.filters.HyperlinkInfo;
|
||||
import com.intellij.execution.filters.TextConsoleBuilderFactory;
|
||||
@@ -24,6 +23,7 @@ import com.intellij.execution.process.ProcessHandler;
|
||||
import com.intellij.execution.ui.ConsoleView;
|
||||
import com.intellij.execution.ui.ConsoleViewContentType;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
@@ -61,8 +61,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.CompoundBorder;
|
||||
import javax.swing.event.TreeSelectionEvent;
|
||||
import javax.swing.event.TreeSelectionListener;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import javax.swing.table.TableColumn;
|
||||
@@ -644,12 +642,13 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon
|
||||
.createActionToolbar("BuildResults", new DefaultActionGroup(consoleActions), false);
|
||||
myPanel.add(toolbar.getComponent(), BorderLayout.EAST);
|
||||
myPanel.setVisible(false);
|
||||
tree.addTreeSelectionListener(new TreeSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(TreeSelectionEvent e) {
|
||||
TreePath path = tree.getSelectionPath();
|
||||
setNode(path != null ? (DefaultMutableTreeNode)path.getLastPathComponent() : null);
|
||||
tree.addTreeSelectionListener(e -> {
|
||||
TreePath path = e.getPath();
|
||||
if (path == null || !e.isAddedPath()) {
|
||||
return;
|
||||
}
|
||||
TreePath selectionPath = tree.getSelectionPath();
|
||||
setNode(selectionPath != null ? (DefaultMutableTreeNode)selectionPath.getLastPathComponent() : null);
|
||||
});
|
||||
|
||||
Disposer.register(threeComponentsSplitter, myConsole);
|
||||
@@ -670,7 +669,7 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon
|
||||
text = failure.getError().getMessage();
|
||||
}
|
||||
if (text == null) continue;
|
||||
printDetails((FailureImpl)failure, text);
|
||||
printDetails(failure, text);
|
||||
hasChanged = true;
|
||||
if (iterator.hasNext()) {
|
||||
myConsole.print("\n\n", ConsoleViewContentType.NORMAL_OUTPUT);
|
||||
@@ -690,7 +689,7 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon
|
||||
return true;
|
||||
}
|
||||
|
||||
public void printDetails(FailureImpl failure, String text) {
|
||||
public void printDetails(Failure failure, String text) {
|
||||
String content = StringUtil.convertLineSeparators(text);
|
||||
while (true) {
|
||||
Matcher tagMatcher = TAG_PATTERN.matcher(content);
|
||||
@@ -709,11 +708,10 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon
|
||||
myConsole.printHyperlink(linkText, new HyperlinkInfo() {
|
||||
@Override
|
||||
public void navigate(Project project) {
|
||||
NotificationData notificationData = failure.getNotificationData();
|
||||
if (notificationData != null) {
|
||||
notificationData.getListener().hyperlinkUpdate(
|
||||
notificationData.getNotification(),
|
||||
IJSwingUtilities.createHyperlinkEvent(href, myConsole.getComponent()));
|
||||
Notification notification = failure.getNotification();
|
||||
if (notification != null && notification.getListener() != null) {
|
||||
notification.getListener().hyperlinkUpdate(
|
||||
notification, IJSwingUtilities.createHyperlinkEvent(href, myConsole.getComponent()));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.intellij.build;
|
||||
|
||||
import com.intellij.build.events.*;
|
||||
import com.intellij.build.events.impl.FailureImpl;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.projectView.PresentationData;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -148,7 +147,7 @@ public class ExecutionNode extends CachingSimpleNode {
|
||||
final long duration = startTime == 0 ? 0 : System.currentTimeMillis() - startTime;
|
||||
String durationText = StringUtil.formatDuration(duration);
|
||||
int index = durationText.indexOf("s ");
|
||||
if(index != -1) {
|
||||
if (index != -1) {
|
||||
durationText = durationText.substring(0, index + 1);
|
||||
}
|
||||
return "Running for " + durationText;
|
||||
@@ -218,10 +217,7 @@ public class ExecutionNode extends CachingSimpleNode {
|
||||
if (myResult instanceof FailureResult) {
|
||||
List<Navigatable> result = new SmartList<>();
|
||||
for (Failure failure : ((FailureResult)myResult).getFailures()) {
|
||||
NotificationData notificationData = ((FailureImpl)failure).getNotificationData();
|
||||
if (notificationData != null) {
|
||||
ContainerUtil.addIfNotNull(result, notificationData.getNavigatable());
|
||||
}
|
||||
ContainerUtil.addIfNotNull(result, failure.getNavigatable());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ public class MultipleBuildsView implements BuildProgressListener, Disposable {
|
||||
Disposer.register(view, contentDescriptor);
|
||||
}
|
||||
else {
|
||||
myBuildContentManager.setSelectedContent(myContent, true, true, true, null);
|
||||
myBuildContentManager.setSelectedContent(myContent, true, true, false, null);
|
||||
}
|
||||
buildInfo.content = myContent;
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.intellij.build.events;
|
||||
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -32,7 +34,13 @@ public interface Failure {
|
||||
String getDescription();
|
||||
|
||||
@Nullable
|
||||
Throwable getError();
|
||||
default Throwable getError() {return null;}
|
||||
|
||||
List<? extends Failure> getCauses();
|
||||
|
||||
@Nullable
|
||||
default Notification getNotification() {return null;}
|
||||
|
||||
@Nullable
|
||||
default Navigatable getNavigatable() {return null;}
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.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.build.events;
|
||||
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationListener;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public interface NotificationData {
|
||||
|
||||
@NotNull
|
||||
Notification getNotification();
|
||||
|
||||
@NotNull
|
||||
NotificationListener getListener();
|
||||
|
||||
@Nullable
|
||||
Navigatable getNavigatable();
|
||||
}
|
||||
@@ -16,7 +16,8 @@
|
||||
package com.intellij.build.events.impl;
|
||||
|
||||
import com.intellij.build.events.Failure;
|
||||
import com.intellij.build.events.NotificationData;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -32,34 +33,38 @@ public class FailureImpl implements Failure {
|
||||
private final List<? extends Failure> myCauses;
|
||||
private final Throwable myError;
|
||||
@Nullable
|
||||
private final NotificationData myNotificationData;
|
||||
private final Notification myNotification;
|
||||
@Nullable
|
||||
private final Navigatable myNavigatable;
|
||||
|
||||
public FailureImpl(String message, Throwable error) {
|
||||
this(message, null, Collections.emptyList(), error, null);
|
||||
this(message, null, Collections.emptyList(), error, null, null);
|
||||
}
|
||||
|
||||
public FailureImpl(String message, Throwable error, @Nullable NotificationData notificationData) {
|
||||
this(message, null, Collections.emptyList(), error, notificationData);
|
||||
public FailureImpl(String message, Throwable error, @Nullable Notification notification, @Nullable Navigatable navigatable) {
|
||||
this(message, null, Collections.emptyList(), error, notification, navigatable);
|
||||
}
|
||||
|
||||
public FailureImpl(String message, String description) {
|
||||
this(message, description, Collections.emptyList(), null, null);
|
||||
this(message, description, Collections.emptyList(), null, null, null);
|
||||
}
|
||||
|
||||
public FailureImpl(String message, String description, List<? extends Failure> causes) {
|
||||
this(message, description, causes, null, null);
|
||||
this(message, description, causes, null, null, null);
|
||||
}
|
||||
|
||||
private FailureImpl(String message,
|
||||
String description,
|
||||
List<? extends Failure> causes,
|
||||
Throwable error,
|
||||
@Nullable NotificationData notificationData) {
|
||||
@Nullable Notification notification,
|
||||
@Nullable Navigatable navigatable) {
|
||||
myMessage = message;
|
||||
myDescription = description;
|
||||
myCauses = causes;
|
||||
myError = error;
|
||||
myNotificationData = notificationData;
|
||||
myNotification = notification;
|
||||
myNavigatable = navigatable;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -86,7 +91,14 @@ public class FailureImpl implements Failure {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public NotificationData getNotificationData() {
|
||||
return myNotificationData;
|
||||
@Override
|
||||
public Notification getNotification() {
|
||||
return myNotification;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Navigatable getNavigatable() {
|
||||
return myNavigatable;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.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.build.events.impl;
|
||||
|
||||
import com.intellij.build.events.NotificationData;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationListener;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
*/
|
||||
public class NotificationDataImpl implements NotificationData {
|
||||
@NotNull private final Notification notification;
|
||||
@NotNull private final NotificationListener myListener;
|
||||
@Nullable private final Navigatable navigatable;
|
||||
|
||||
public NotificationDataImpl(@NotNull Notification notification,
|
||||
@NotNull NotificationListener listener,
|
||||
@Nullable Navigatable navigatable) {
|
||||
this.notification = notification;
|
||||
myListener = listener;
|
||||
this.navigatable = navigatable;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Notification getNotification() {
|
||||
return notification;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public NotificationListener getListener() {
|
||||
return myListener;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Navigatable getNavigatable() {
|
||||
return navigatable;
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import com.intellij.util.TripleFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -34,6 +35,8 @@ public final class CompilerMessageImpl implements CompilerMessage {
|
||||
private final VirtualFile myFile;
|
||||
private final int myRow;
|
||||
private final int myColumn;
|
||||
@NotNull
|
||||
private TripleFunction<CompilerMessage, Integer, Integer, Integer> myColumnAdjuster = (msg, line, col) -> col;
|
||||
|
||||
public CompilerMessageImpl(Project project, CompilerMessageCategory category, String message) {
|
||||
this(project, category, message, null, -1, -1, null);
|
||||
@@ -55,6 +58,10 @@ public final class CompilerMessageImpl implements CompilerMessage {
|
||||
myFile = file;
|
||||
}
|
||||
|
||||
public void setColumnAdjuster(@NotNull TripleFunction<CompilerMessage, Integer, Integer, Integer> columnAdjuster) {
|
||||
myColumnAdjuster = columnAdjuster;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CompilerMessageCategory getCategory() {
|
||||
@@ -75,7 +82,7 @@ public final class CompilerMessageImpl implements CompilerMessage {
|
||||
if (virtualFile != null && virtualFile.isValid()) {
|
||||
final int line = getLine() - 1; // editor lines are zero-based
|
||||
if (line >= 0) {
|
||||
return myNavigatable = new OpenFileDescriptor(myProject, virtualFile, line, Math.max(0, getColumn()-1));
|
||||
return myNavigatable = new OpenFileDescriptor(myProject, virtualFile, line, myColumnAdjuster.fun(this, line, Math.max(0, getColumn()-1))) ;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ import org.jdom.Element
|
||||
import org.jetbrains.jps.model.serialization.java.compiler.JpsJavaCompilerConfigurationSerializer
|
||||
import java.util.*
|
||||
|
||||
@State(name = "ExternalCompilerConfigurationStorage", storages = arrayOf(Storage("compiler.xml")), externalStorageOnly = true)
|
||||
@State(name = "ExternalCompilerConfiguration", storages = arrayOf(Storage("compiler.xml")), externalStorageOnly = true)
|
||||
internal class ExternalCompilerConfigurationStorage(private val project: Project) : PersistentStateComponent<Element>, ProjectModelElement {
|
||||
var loadedState: Map<String, String>? = null
|
||||
private set
|
||||
|
||||
@@ -15,10 +15,16 @@
|
||||
*/
|
||||
package com.intellij.compiler.impl;
|
||||
|
||||
import com.intellij.codeStyle.CodeStyleFacade;
|
||||
import com.intellij.compiler.CompilerMessageImpl;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.CompilerMessage;
|
||||
import com.intellij.openapi.compiler.CompilerMessageCategory;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.pom.Navigatable;
|
||||
@@ -32,11 +38,15 @@ import java.util.*;
|
||||
* Date: 27-Jan-16
|
||||
*/
|
||||
public class MessagesContainer {
|
||||
|
||||
private static final int JAVAC_TAB_SIZE = 8;
|
||||
private final Project myProject;
|
||||
private final Map<CompilerMessageCategory, Collection<CompilerMessage>> myMessages = new EnumMap<>(CompilerMessageCategory.class);
|
||||
private final int myTabSize;
|
||||
|
||||
public MessagesContainer(Project project) {
|
||||
myProject = project;
|
||||
myTabSize = CodeStyleFacade.getInstance().getTabSize(StdFileTypes.JAVA);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -52,11 +62,49 @@ public class MessagesContainer {
|
||||
public CompilerMessage addMessage(CompilerMessageCategory category, String message, String url, int lineNum, int columnNum, Navigatable navigatable) {
|
||||
CompilerMessageImpl msg = new CompilerMessageImpl(myProject, category, message, findFileByUrl(url), lineNum, columnNum, navigatable);
|
||||
if (addMessage(msg)) {
|
||||
msg.setColumnAdjuster((m, line, col) -> adjustColumn(m, line, col));
|
||||
return msg;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int adjustColumn(final CompilerMessage m, final int line, final int col) {
|
||||
if (myTabSize != JAVAC_TAB_SIZE && line >= 1) {
|
||||
// javac uses hard-coded tab size 8 chars. So recalculate only if project's codestyle is different
|
||||
final VirtualFile file = m.getVirtualFile();
|
||||
if (file != null && file.isValid()) {
|
||||
final int tabCount = ApplicationManager.getApplication().runReadAction((Computable<Integer>)() -> {
|
||||
final Document doc = FileDocumentManager.getInstance().getDocument(file);
|
||||
if (doc == null) {
|
||||
return 0;
|
||||
}
|
||||
int tcount = 0;
|
||||
final CharSequence seq = doc.getCharsSequence();
|
||||
final int start = doc.getLineStartOffset(line);
|
||||
final int end = doc.getLineEndOffset(line);
|
||||
int charsExpanded = 0;
|
||||
for (int i = start; i< end; i++) {
|
||||
if (seq.charAt(i) == '\t') {
|
||||
charsExpanded += JAVAC_TAB_SIZE;
|
||||
tcount++;
|
||||
}
|
||||
else {
|
||||
charsExpanded += 1;
|
||||
}
|
||||
if (charsExpanded >= col) {
|
||||
break; // consider only those tabs that are located before the given column number
|
||||
}
|
||||
}
|
||||
return tcount;
|
||||
});
|
||||
if (tabCount > 0) {
|
||||
return Math.max(0, col + tabCount * (myTabSize - JAVAC_TAB_SIZE));
|
||||
}
|
||||
}
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
public boolean addMessage(CompilerMessage msg) {
|
||||
Collection<CompilerMessage> messages = myMessages.computeIfAbsent(msg.getCategory(), k -> new LinkedHashSet<>());
|
||||
return messages.add(msg);
|
||||
|
||||
+7
-1
@@ -40,6 +40,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
|
||||
private JCheckBox myCbShowObjectId;
|
||||
private JCheckBox myCbShowStringsType;
|
||||
private JCheckBox myCbHexValue;
|
||||
private JCheckBox myCbPopulateThrowableStack;
|
||||
|
||||
private StateRestoringCheckBox myCbShowStaticFinalFields;
|
||||
//private final ArrayRendererConfigurable myArrayRendererConfigurable;
|
||||
@@ -110,6 +111,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
|
||||
myCbShowObjectId = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.show.object.id"));
|
||||
myCbHexValue = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.show.hex.value"));
|
||||
myCbShowStringsType = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.show.strings.type"));
|
||||
myCbPopulateThrowableStack = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.populate.throwable.stack"));
|
||||
|
||||
myCbEnableToString = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.enable.toString"));
|
||||
myRbAllThatOverride = new JRadioButton(DebuggerBundle.message("label.base.renderer.configurable.all.overriding"));
|
||||
@@ -160,6 +162,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
|
||||
panel.add(myCbShowStringsType, new GridBagConstraints(0, RELATIVE, 3, 1, 1.0, 0.0, NORTH, HORIZONTAL, JBUI.emptyInsets(), 0, 0));
|
||||
panel.add(myCbHexValue, new GridBagConstraints(0, RELATIVE, 3, 1, 1.0, 0.0, NORTH, HORIZONTAL, JBUI.insetsTop(4), 0, 0));
|
||||
panel.add(myCbHideNullArrayElements, new GridBagConstraints(0, RELATIVE, 3, 1, 1.0, 0.0, NORTH, HORIZONTAL, JBUI.insetsTop(4), 0, 0));
|
||||
panel.add(myCbPopulateThrowableStack, new GridBagConstraints(0, RELATIVE, 3, 1, 1.0, 0.0, NORTH, HORIZONTAL, JBUI.insetsTop(4), 0, 0));
|
||||
|
||||
panel.add(myCbEnableAlternateViews, new GridBagConstraints(0, RELATIVE, 1, 1, 0.0, 0.0, WEST, NONE, JBUI.insets(4, 0, 0, 10), 0, 0));
|
||||
// starting 4-th row
|
||||
@@ -180,6 +183,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
|
||||
generalSettings.AUTOSCROLL_TO_NEW_LOCALS = myCbAutoscroll.isSelected();
|
||||
rendererSettings.setAlternateCollectionViewsEnabled(myCbEnableAlternateViews.isSelected());
|
||||
generalSettings.HIDE_NULL_ARRAY_ELEMENTS = myCbHideNullArrayElements.isSelected();
|
||||
generalSettings.POPULATE_THROWABLE_STACKTRACE = myCbPopulateThrowableStack.isSelected();
|
||||
|
||||
final ClassRenderer classRenderer = rendererSettings.getClassRenderer();
|
||||
classRenderer.SHOW_STATIC = myCbShowStatic.isSelected();
|
||||
@@ -210,6 +214,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
|
||||
myCbAutoscroll.setSelected(generalSettings.AUTOSCROLL_TO_NEW_LOCALS);
|
||||
myCbHideNullArrayElements.setSelected(generalSettings.HIDE_NULL_ARRAY_ELEMENTS);
|
||||
myCbEnableAlternateViews.setSelected(rendererSettings.areAlternateCollectionViewsEnabled());
|
||||
myCbPopulateThrowableStack.setSelected(generalSettings.POPULATE_THROWABLE_STACKTRACE);
|
||||
|
||||
ClassRenderer classRenderer = rendererSettings.getClassRenderer();
|
||||
|
||||
@@ -251,7 +256,8 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
|
||||
private boolean areGeneralSettingsModified() {
|
||||
ViewsGeneralSettings generalSettings = ViewsGeneralSettings.getInstance();
|
||||
return generalSettings.AUTOSCROLL_TO_NEW_LOCALS != myCbAutoscroll.isSelected() ||
|
||||
generalSettings.HIDE_NULL_ARRAY_ELEMENTS != myCbHideNullArrayElements.isSelected();
|
||||
generalSettings.HIDE_NULL_ARRAY_ELEMENTS != myCbHideNullArrayElements.isSelected() ||
|
||||
generalSettings.POPULATE_THROWABLE_STACKTRACE != myCbPopulateThrowableStack.isSelected();
|
||||
}
|
||||
|
||||
private boolean areDefaultRenderersModified() {
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.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.
|
||||
*/
|
||||
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.debugger.settings;
|
||||
|
||||
import com.intellij.openapi.components.PersistentStateComponent;
|
||||
@@ -29,6 +15,7 @@ public class ViewsGeneralSettings implements PersistentStateComponent<ViewsGener
|
||||
public boolean SHOW_OBJECTID = true;
|
||||
public boolean HIDE_NULL_ARRAY_ELEMENTS = true;
|
||||
public boolean AUTOSCROLL_TO_NEW_LOCALS = true;
|
||||
public boolean POPULATE_THROWABLE_STACKTRACE = true;
|
||||
|
||||
public static ViewsGeneralSettings getInstance() {
|
||||
return ServiceManager.getService(ViewsGeneralSettings.class);
|
||||
@@ -49,6 +36,7 @@ public class ViewsGeneralSettings implements PersistentStateComponent<ViewsGener
|
||||
ViewsGeneralSettings generalSettings = ((ViewsGeneralSettings)object);
|
||||
return SHOW_OBJECTID == generalSettings.SHOW_OBJECTID &&
|
||||
HIDE_NULL_ARRAY_ELEMENTS == generalSettings.HIDE_NULL_ARRAY_ELEMENTS &&
|
||||
AUTOSCROLL_TO_NEW_LOCALS == generalSettings.AUTOSCROLL_TO_NEW_LOCALS;
|
||||
AUTOSCROLL_TO_NEW_LOCALS == generalSettings.AUTOSCROLL_TO_NEW_LOCALS &&
|
||||
POPULATE_THROWABLE_STACKTRACE == generalSettings.POPULATE_THROWABLE_STACKTRACE;
|
||||
}
|
||||
}
|
||||
|
||||
+13
-5
@@ -14,10 +14,10 @@ import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.PositionUtil;
|
||||
import com.intellij.debugger.settings.NodeRendererSettings;
|
||||
import com.intellij.debugger.settings.ViewsGeneralSettings;
|
||||
import com.intellij.debugger.ui.tree.FieldDescriptor;
|
||||
import com.intellij.debugger.ui.tree.NodeDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.CommonClassNames;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
@@ -84,8 +84,12 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes
|
||||
DebuggerManagerThreadImpl.assertIsManagerThread();
|
||||
try {
|
||||
if (myObject != null) {
|
||||
populateExceptionStackTraceIfNeeded(evaluationContext);
|
||||
return myObject.getValue(myField);
|
||||
Value fieldValue = myObject.getValue(myField);
|
||||
if (populateExceptionStackTraceIfNeeded(fieldValue, evaluationContext)) {
|
||||
// re-read stacktrace value
|
||||
fieldValue = myObject.getValue(myField);
|
||||
}
|
||||
return fieldValue;
|
||||
}
|
||||
else {
|
||||
return myField.declaringType().getValue(myField);
|
||||
@@ -96,17 +100,21 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes
|
||||
}
|
||||
}
|
||||
|
||||
private void populateExceptionStackTraceIfNeeded(EvaluationContextImpl evaluationContext) {
|
||||
private boolean populateExceptionStackTraceIfNeeded(Value value, EvaluationContextImpl evaluationContext) {
|
||||
if ("stackTrace".equals(getName()) &&
|
||||
Registry.is("debugger.populate.exception.stack") &&
|
||||
ViewsGeneralSettings.getInstance().POPULATE_THROWABLE_STACKTRACE &&
|
||||
value instanceof ArrayReference &&
|
||||
((ArrayReference)value).length() == 0 &&
|
||||
DebuggerUtils.instanceOf(myObject.type(), CommonClassNames.JAVA_LANG_THROWABLE)) {
|
||||
try {
|
||||
invokeExceptionGetStackTrace(myObject, evaluationContext);
|
||||
return true;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.info(e); // catch all exceptions to ensure the method returns gracefully
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
|
||||
+3
@@ -19,6 +19,7 @@ import com.intellij.execution.configuration.RunConfigurationExtensionsManager;
|
||||
import com.intellij.execution.configurations.RunConfigurationBase;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class JavaRunConfigurationExtensionManager extends RunConfigurationExtensionsManager<RunConfigurationBase, RunConfigurationExtension> {
|
||||
private static final Logger LOG = Logger.getInstance(RunConfigurationExtension.class);
|
||||
@@ -40,11 +41,13 @@ public class JavaRunConfigurationExtensionManager extends RunConfigurationExtens
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getIdAttrName() {
|
||||
return "name";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getExtensionRootAttr() {
|
||||
return "extension";
|
||||
|
||||
+1
-5
@@ -189,11 +189,7 @@ public class ExistingLibraryEditor extends LibraryEditorBase implements Disposab
|
||||
|
||||
@Override
|
||||
public void removeRoot(@NotNull String url, @NotNull OrderRootType rootType) {
|
||||
boolean removed;
|
||||
do {
|
||||
removed = getModel().removeRoot(url, rootType);
|
||||
}
|
||||
while (removed);
|
||||
getModel().removeRoot(url, rootType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,30 +1,13 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.psi.PsiDocCommentOwner;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface BatchSuppressManager {
|
||||
String SUPPRESS_INSPECTIONS_ANNOTATION_NAME = "java.lang.SuppressWarnings";
|
||||
|
||||
@@ -38,17 +21,6 @@ public interface BatchSuppressManager {
|
||||
|
||||
boolean isSuppressedFor(@NotNull PsiElement element, @NotNull String toolId);
|
||||
|
||||
PsiElement getElementMemberSuppressedIn(@NotNull PsiDocCommentOwner owner, @NotNull String inspectionToolID);
|
||||
|
||||
@Nullable
|
||||
PsiElement getAnnotationMemberSuppressedIn(@NotNull PsiModifierListOwner owner, @NotNull String inspectionToolID);
|
||||
|
||||
@Nullable
|
||||
PsiElement getDocCommentToolSuppressedIn(@NotNull PsiDocCommentOwner owner, @NotNull String inspectionToolID);
|
||||
|
||||
@NotNull
|
||||
Collection<String> getInspectionIdsSuppressedInAnnotation(@NotNull PsiModifierListOwner owner);
|
||||
|
||||
@Nullable
|
||||
String getSuppressedInspectionIdsIn(@NotNull PsiElement element);
|
||||
|
||||
|
||||
@@ -21,5 +21,6 @@
|
||||
<orderEntry type="library" exported="" name="ASM" level="project" />
|
||||
<orderEntry type="library" name="StreamEx" level="project" />
|
||||
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
|
||||
<orderEntry type="module" module-name="openapi" />
|
||||
</component>
|
||||
</module>
|
||||
+7
-1
@@ -785,9 +785,15 @@ public class AnnotationsHighlightUtil {
|
||||
return getText();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement getElementToMakeWritable(@NotNull PsiFile currentFile) {
|
||||
return myAnnotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return true;
|
||||
return myAnnotation.isValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-5
@@ -50,7 +50,7 @@ public class ExpressionTypeMemoryState extends DfaMemoryStateImpl {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
private final MultiMap<PsiExpression, PsiType> myStates = MultiMap.create(EXPRESSION_HASHING_STRATEGY);
|
||||
private final MultiMap<PsiExpression, PsiType> myStates = MultiMap.createSet(EXPRESSION_HASHING_STRATEGY);
|
||||
|
||||
public ExpressionTypeMemoryState(final DfaValueFactory factory) {
|
||||
super(factory);
|
||||
@@ -75,6 +75,7 @@ public class ExpressionTypeMemoryState extends DfaMemoryStateImpl {
|
||||
if (!value.isNegated()) {
|
||||
setExpressionType(value.getExpression(), value.getCastType());
|
||||
}
|
||||
return super.applyCondition(((DfaInstanceofValue)dfaCond).getRelation());
|
||||
}
|
||||
|
||||
return super.applyCondition(dfaCond);
|
||||
@@ -91,10 +92,7 @@ public class ExpressionTypeMemoryState extends DfaMemoryStateImpl {
|
||||
if (!super.equals(o)) return false;
|
||||
|
||||
ExpressionTypeMemoryState that = (ExpressionTypeMemoryState)o;
|
||||
|
||||
if (!myStates.equals(that.myStates)) return false;
|
||||
|
||||
return true;
|
||||
return myStates.equals(that.myStates);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+103
-32
@@ -17,11 +17,10 @@ package com.intellij.codeInsight.guess.impl;
|
||||
|
||||
import com.intellij.codeInsight.guess.GuessManager;
|
||||
import com.intellij.codeInspection.dataFlow.*;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.InstanceofInstruction;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.MethodCallInstruction;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.PushInstruction;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.TypeCastInstruction;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.*;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaInstanceofValue;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaRelationValue;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaValue;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
@@ -36,7 +35,7 @@ import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.BitUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import gnu.trove.THashMap;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -156,33 +155,60 @@ public class GuessManagerImpl extends GuessManager {
|
||||
};
|
||||
|
||||
final ExpressionTypeInstructionVisitor visitor = new ExpressionTypeInstructionVisitor(forPlace);
|
||||
if (runner.analyzeMethod(scope, visitor) == RunnerResult.OK) {
|
||||
if (runner.analyzeMethodWithInlining(scope, visitor) == RunnerResult.OK) {
|
||||
return visitor.getResult();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Map<PsiExpression, PsiType> getAllTypeCasts(PsiExpression forPlace) {
|
||||
assert forPlace.isValid();
|
||||
final int start = forPlace.getTextRange().getStartOffset();
|
||||
final Map<PsiExpression, PsiType> allCasts = new THashMap<>(ExpressionTypeMemoryState.EXPRESSION_HASHING_STRATEGY);
|
||||
getTopmostBlock(forPlace).accept(new JavaRecursiveElementWalkingVisitor() {
|
||||
private static boolean mayHaveMorePreciseType(PsiExpression expr) {
|
||||
PsiExpression place = PsiUtil.skipParenthesizedExprDown(expr);
|
||||
if (place instanceof PsiReferenceExpression) {
|
||||
PsiElement target = ((PsiReferenceExpression)place).resolve();
|
||||
if (target instanceof PsiParameter) {
|
||||
PsiElement parent = target.getParent();
|
||||
if (parent instanceof PsiParameterList && parent.getParent() instanceof PsiLambdaExpression) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (place == null) return false;
|
||||
final int start = place.getTextRange().getStartOffset();
|
||||
class Visitor extends JavaRecursiveElementWalkingVisitor {
|
||||
public boolean hasInteresting;
|
||||
|
||||
@Override
|
||||
public void visitAssignmentExpression(PsiAssignmentExpression expression) {
|
||||
if (ExpressionTypeMemoryState.EXPRESSION_HASHING_STRATEGY.equals(expression.getLExpression(), place)) {
|
||||
hasInteresting = true;
|
||||
stopWalking();
|
||||
}
|
||||
super.visitAssignmentExpression(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLocalVariable(PsiLocalVariable variable) {
|
||||
if (variable.getInitializer() != null && ExpressionUtils.isReferenceTo(place, variable)) {
|
||||
hasInteresting = true;
|
||||
stopWalking();
|
||||
}
|
||||
super.visitLocalVariable(variable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeCastExpression(PsiTypeCastExpression expression) {
|
||||
final PsiType castType = expression.getType();
|
||||
final PsiExpression operand = expression.getOperand();
|
||||
if (operand != null && castType != null) {
|
||||
allCasts.put(operand, castType);
|
||||
if (ExpressionTypeMemoryState.EXPRESSION_HASHING_STRATEGY.equals(expression.getOperand(), place)) {
|
||||
hasInteresting = true;
|
||||
stopWalking();
|
||||
}
|
||||
super.visitTypeCastExpression(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInstanceOfExpression(PsiInstanceOfExpression expression) {
|
||||
final PsiTypeElement castType = expression.getCheckType();
|
||||
final PsiExpression operand = expression.getOperand();
|
||||
if (castType != null) {
|
||||
allCasts.put(operand, castType.getType());
|
||||
if (ExpressionTypeMemoryState.EXPRESSION_HASHING_STRATEGY.equals(expression.getOperand(), place)) {
|
||||
hasInteresting = true;
|
||||
stopWalking();
|
||||
}
|
||||
super.visitInstanceOfExpression(expression);
|
||||
}
|
||||
@@ -190,13 +216,14 @@ public class GuessManagerImpl extends GuessManager {
|
||||
@Override
|
||||
public void visitElement(PsiElement element) {
|
||||
if (element.getTextRange().getStartOffset() > start) {
|
||||
return;
|
||||
stopWalking();
|
||||
}
|
||||
|
||||
super.visitElement(element);
|
||||
}
|
||||
});
|
||||
return allCasts;
|
||||
}
|
||||
Visitor visitor = new Visitor();
|
||||
getTopmostBlock(place).accept(visitor);
|
||||
return visitor.hasInteresting;
|
||||
}
|
||||
|
||||
private static PsiElement getTopmostBlock(PsiElement scope) {
|
||||
@@ -375,8 +402,7 @@ public class GuessManagerImpl extends GuessManager {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<PsiType> getControlFlowExpressionTypeConjuncts(@NotNull PsiExpression expr) {
|
||||
final Map<PsiExpression, PsiType> allCasts = getAllTypeCasts(expr);
|
||||
if (!allCasts.containsKey(expr)) {
|
||||
if (!mayHaveMorePreciseType(expr)) {
|
||||
return Collections.emptyList(); //optimization
|
||||
}
|
||||
|
||||
@@ -391,9 +417,10 @@ public class GuessManagerImpl extends GuessManager {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private static class ExpressionTypeInstructionVisitor extends InstructionVisitor {
|
||||
private static class ExpressionTypeInstructionVisitor extends StandardInstructionVisitor {
|
||||
private MultiMap<PsiExpression, PsiType> myResult;
|
||||
private final PsiElement myForPlace;
|
||||
private TypeConstraint myConstraint = null;
|
||||
|
||||
private ExpressionTypeInstructionVisitor(@NotNull PsiElement forPlace) {
|
||||
PsiElement parent = PsiUtil.skipParenthesizedExprUp(forPlace.getParent());
|
||||
@@ -405,14 +432,24 @@ public class GuessManagerImpl extends GuessManager {
|
||||
}
|
||||
|
||||
MultiMap<PsiExpression, PsiType> getResult() {
|
||||
if (myConstraint != null && myForPlace instanceof PsiExpression) {
|
||||
PsiType type = myConstraint.getPsiType();
|
||||
if (type instanceof PsiIntersectionType) {
|
||||
myResult.putValues((PsiExpression)myForPlace, Arrays.asList(((PsiIntersectionType)type).getConjuncts()));
|
||||
}
|
||||
else {
|
||||
myResult.putValue((PsiExpression)myForPlace, type);
|
||||
}
|
||||
}
|
||||
return myResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DfaInstructionState[] visitInstanceof(InstanceofInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
|
||||
memState.pop();
|
||||
memState.pop();
|
||||
memState.push(new DfaInstanceofValue(runner.getFactory(), instruction.getLeft(), instruction.getCastType()));
|
||||
DfaValue type = memState.pop();
|
||||
DfaValue operand = memState.pop();
|
||||
DfaValue relation = runner.getFactory().createCondition(operand, DfaRelationValue.RelationType.IS, type);
|
||||
memState.push(new DfaInstanceofValue(runner.getFactory(), instruction.getLeft(), instruction.getCastType(), relation, false));
|
||||
return new DfaInstructionState[]{new DfaInstructionState(runner.getInstruction(instruction.getIndex() + 1), memState)};
|
||||
}
|
||||
|
||||
@@ -422,12 +459,27 @@ public class GuessManagerImpl extends GuessManager {
|
||||
return super.visitTypeCast(instruction, runner, memState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DfaInstructionState[] visitAssign(AssignInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
|
||||
PsiExpression left = instruction.getLExpression();
|
||||
PsiExpression right = instruction.getRExpression();
|
||||
if (left != null && right != null) {
|
||||
MultiMap<PsiExpression, PsiType> states = ((ExpressionTypeMemoryState)memState).getStates();
|
||||
states.remove(left);
|
||||
}
|
||||
return super.visitAssign(instruction, runner, memState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DfaInstructionState[] visitMethodCall(MethodCallInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
|
||||
if (myForPlace == instruction.getCallExpression()) {
|
||||
addToResult(((ExpressionTypeMemoryState)memState).getStates());
|
||||
}
|
||||
return super.visitMethodCall(instruction, runner, memState);
|
||||
DfaInstructionState[] states = super.visitMethodCall(instruction, runner, memState);
|
||||
if (myForPlace == instruction.getCallExpression()) {
|
||||
addConstraints(states);
|
||||
}
|
||||
return states;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -435,12 +487,31 @@ public class GuessManagerImpl extends GuessManager {
|
||||
if (myForPlace == instruction.getPlace()) {
|
||||
addToResult(((ExpressionTypeMemoryState)memState).getStates());
|
||||
}
|
||||
return super.visitPush(instruction, runner, memState);
|
||||
DfaInstructionState[] states = super.visitPush(instruction, runner, memState);
|
||||
if (myForPlace == instruction.getPlace()) {
|
||||
addConstraints(states);
|
||||
}
|
||||
return states;
|
||||
}
|
||||
|
||||
private void addConstraints(DfaInstructionState[] states) {
|
||||
for (DfaInstructionState state : states) {
|
||||
DfaMemoryState memoryState = state.getMemoryState();
|
||||
if (myConstraint == TypeConstraint.EMPTY) return;
|
||||
TypeConstraint constraint = memoryState.getValueFact(memoryState.peek(), DfaFactType.TYPE_CONSTRAINT);
|
||||
if (constraint != null) {
|
||||
myConstraint = myConstraint == null ? constraint : myConstraint.union(constraint);
|
||||
if (myConstraint == null) {
|
||||
myConstraint = TypeConstraint.EMPTY;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addToResult(MultiMap<PsiExpression, PsiType> map) {
|
||||
if (myResult == null) {
|
||||
myResult = MultiMap.create(ExpressionTypeMemoryState.EXPRESSION_HASHING_STRATEGY);
|
||||
myResult = MultiMap.createSet(ExpressionTypeMemoryState.EXPRESSION_HASHING_STRATEGY);
|
||||
myResult.putAllValues(map);
|
||||
} else {
|
||||
final Iterator<PsiExpression> iterator = myResult.keySet().iterator();
|
||||
|
||||
+1
-42
@@ -1,30 +1,13 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
|
||||
import com.intellij.codeInsight.daemon.impl.actions.*;
|
||||
import com.intellij.psi.PsiDocCommentOwner;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class BatchSuppressManagerImpl implements BatchSuppressManager {
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -45,30 +28,6 @@ public class BatchSuppressManagerImpl implements BatchSuppressManager {
|
||||
return JavaSuppressionUtil.getElementToolSuppressedIn(element, toolId) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiElement getElementMemberSuppressedIn(@NotNull final PsiDocCommentOwner owner, @NotNull final String inspectionToolID) {
|
||||
return JavaSuppressionUtil.getElementMemberSuppressedIn(owner, inspectionToolID);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiElement getAnnotationMemberSuppressedIn(@NotNull final PsiModifierListOwner owner, @NotNull final String inspectionToolID) {
|
||||
return JavaSuppressionUtil.getAnnotationMemberSuppressedIn(owner, inspectionToolID);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiElement getDocCommentToolSuppressedIn(@NotNull final PsiDocCommentOwner owner, @NotNull final String inspectionToolID) {
|
||||
return JavaSuppressionUtil.getDocCommentToolSuppressedIn(owner, inspectionToolID);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Collection<String> getInspectionIdsSuppressedInAnnotation(@NotNull final PsiModifierListOwner owner) {
|
||||
return JavaSuppressionUtil.getInspectionIdsSuppressedInAnnotation(owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getSuppressedInspectionIdsIn(@NotNull PsiElement element) {
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.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.
|
||||
*/
|
||||
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
@@ -20,12 +6,9 @@ import com.intellij.codeInsight.daemon.HighlightDisplayKey;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.PsiDocCommentOwner;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class SuppressManagerImpl extends SuppressManager {
|
||||
private static final Logger LOG = Logger.getInstance(SuppressManager.class);
|
||||
|
||||
@@ -49,30 +32,6 @@ public class SuppressManagerImpl extends SuppressManager {
|
||||
return JavaSuppressionUtil.getElementToolSuppressedIn(element, toolId) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiElement getElementMemberSuppressedIn(@NotNull final PsiDocCommentOwner owner, @NotNull final String inspectionToolID) {
|
||||
return JavaSuppressionUtil.getElementMemberSuppressedIn(owner, inspectionToolID);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiElement getAnnotationMemberSuppressedIn(@NotNull final PsiModifierListOwner owner, @NotNull final String inspectionToolID) {
|
||||
return JavaSuppressionUtil.getAnnotationMemberSuppressedIn(owner, inspectionToolID);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiElement getDocCommentToolSuppressedIn(@NotNull final PsiDocCommentOwner owner, @NotNull final String inspectionToolID) {
|
||||
return JavaSuppressionUtil.getDocCommentToolSuppressedIn(owner, inspectionToolID);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Collection<String> getInspectionIdsSuppressedInAnnotation(@NotNull final PsiModifierListOwner owner) {
|
||||
return JavaSuppressionUtil.getInspectionIdsSuppressedInAnnotation(owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getSuppressedInspectionIdsIn(@NotNull PsiElement element) {
|
||||
|
||||
+2
-1
@@ -6,6 +6,7 @@ import com.intellij.codeInsight.daemon.GroupNames;
|
||||
import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
@@ -81,7 +82,7 @@ public class FieldAccessNotGuardedInspection extends AbstractBaseJavaLocalInspec
|
||||
if (guardExpression instanceof PsiThisExpression) {
|
||||
final PsiThisExpression thisExpression = (PsiThisExpression)guardExpression;
|
||||
final PsiClass aClass = getClassFromThisExpression(thisExpression, field);
|
||||
if (aClass == null || aClass.equals(containingMethod.getContainingClass())) {
|
||||
if (aClass == null || InheritanceUtil.isInheritorOrSelf(containingMethod.getContainingClass(), aClass, true)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -82,7 +82,7 @@ public class CommonDataflow {
|
||||
return states;
|
||||
}
|
||||
};
|
||||
RunnerResult result = runner.analyzeMethod(block, visitor);
|
||||
RunnerResult result = runner.analyzeMethodRecursively(block, visitor);
|
||||
return result == RunnerResult.OK ? dfr : null;
|
||||
}
|
||||
|
||||
|
||||
+1
-20
@@ -18,7 +18,6 @@ import com.intellij.codeInspection.dataFlow.instructions.*;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaConstValue;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaUnknownValue;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaValue;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
|
||||
import com.intellij.codeInspection.nullable.NullableStuffInspectionBase;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -31,7 +30,6 @@ import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.siyeh.ig.psiutils.*;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jdom.Element;
|
||||
@@ -184,24 +182,7 @@ public class DataFlowInspectionBase extends AbstractBaseJavaLocalInspectionTool
|
||||
final RunnerResult rc = dfaRunner.analyzeMethod(scope, visitor, IGNORE_ASSERT_STATEMENTS, initialStates);
|
||||
if (rc == RunnerResult.OK) {
|
||||
createDescription(dfaRunner, holder, visitor, scope);
|
||||
|
||||
MultiMap<PsiElement,DfaMemoryState> nestedClosures = dfaRunner.getNestedClosures();
|
||||
for (PsiElement closure : nestedClosures.keySet()) {
|
||||
List<DfaVariableValue> unusedVars = StreamEx.of(dfaRunner.getFactory().getValues())
|
||||
.select(DfaVariableValue.class)
|
||||
.filter(var -> var.getQualifier() == null)
|
||||
.filter(var -> var.getPsiVariable() instanceof PsiVariable &&
|
||||
!VariableAccessUtils.variableIsUsed((PsiVariable)var.getPsiVariable(), closure))
|
||||
.toList();
|
||||
Collection<? extends DfaMemoryState> states = nestedClosures.get(closure);
|
||||
if (!unusedVars.isEmpty()) {
|
||||
List<DfaMemoryStateImpl> stateList = StreamEx.of(states)
|
||||
.peek(state -> unusedVars.forEach(state::flushVariable))
|
||||
.map(state -> (DfaMemoryStateImpl)state).distinct().toList();
|
||||
states = StateQueue.mergeGroup(stateList);
|
||||
}
|
||||
analyzeDfaWithNestedClosures(closure, holder, dfaRunner, states);
|
||||
}
|
||||
dfaRunner.forNestedClosures((closure, states) -> analyzeDfaWithNestedClosures(closure, holder, dfaRunner, states));
|
||||
}
|
||||
else if (rc == RunnerResult.TOO_COMPLEX) {
|
||||
PsiIdentifier name = null;
|
||||
|
||||
+79
-7
@@ -23,6 +23,7 @@ import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -30,12 +31,14 @@ import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.siyeh.ig.psiutils.VariableAccessUtils;
|
||||
import gnu.trove.THashSet;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class DataFlowRunner {
|
||||
@@ -73,14 +76,16 @@ public class DataFlowRunner {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Collection<DfaMemoryState> createInitialStates(@NotNull PsiElement psiBlock, @NotNull InstructionVisitor visitor) {
|
||||
private Collection<DfaMemoryState> createInitialStates(@NotNull PsiElement psiBlock,
|
||||
@NotNull InstructionVisitor visitor,
|
||||
boolean allowInlining) {
|
||||
PsiElement container = PsiTreeUtil.getParentOfType(psiBlock, PsiClass.class, PsiLambdaExpression.class);
|
||||
if (container != null && (!(container instanceof PsiClass) || PsiUtil.isLocalOrAnonymousClass((PsiClass)container))) {
|
||||
PsiElement block = DfaPsiUtil.getTopmostBlockInSameClass(container.getParent());
|
||||
if (block != null) {
|
||||
final RunnerResult result;
|
||||
try {
|
||||
myInlining = false;
|
||||
myInlining = allowInlining;
|
||||
result = analyzeMethod(block, visitor);
|
||||
}
|
||||
finally {
|
||||
@@ -88,7 +93,7 @@ public class DataFlowRunner {
|
||||
}
|
||||
if (result == RunnerResult.OK) {
|
||||
final Collection<DfaMemoryState> closureStates = myNestedClosures.get(DfaPsiUtil.getTopmostBlockInSameClass(psiBlock));
|
||||
if (!closureStates.isEmpty()) {
|
||||
if (allowInlining || !closureStates.isEmpty()) {
|
||||
return closureStates;
|
||||
}
|
||||
}
|
||||
@@ -99,12 +104,41 @@ public class DataFlowRunner {
|
||||
return Collections.singletonList(createMemoryState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyze this particular method (lambda, class initializer) without inlining this method into parent one.
|
||||
* E.g. if supplied method is a lambda within Stream API call chain, it still will be analyzed as separate method.
|
||||
* On the other hand, inlining will normally work inside the supplied method.
|
||||
*
|
||||
* @param psiBlock method/lambda/class initializer body
|
||||
* @param visitor a visitor to use
|
||||
* @return result status
|
||||
*/
|
||||
@NotNull
|
||||
public final RunnerResult analyzeMethod(@NotNull PsiElement psiBlock, @NotNull InstructionVisitor visitor) {
|
||||
Collection<DfaMemoryState> initialStates = createInitialStates(psiBlock, visitor);
|
||||
Collection<DfaMemoryState> initialStates = createInitialStates(psiBlock, visitor, false);
|
||||
return initialStates == null ? RunnerResult.NOT_APPLICABLE : analyzeMethod(psiBlock, visitor, false, initialStates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyze this particular method (lambda, class initializer) trying to inline it into outer scope if possible.
|
||||
* Usually inlining works, e.g. for lambdas inside stream API calls.
|
||||
*
|
||||
* @param psiBlock method/lambda/class initializer body
|
||||
* @param visitor a visitor to use
|
||||
* @return result status
|
||||
*/
|
||||
@NotNull
|
||||
public final RunnerResult analyzeMethodWithInlining(@NotNull PsiElement psiBlock, @NotNull InstructionVisitor visitor) {
|
||||
Collection<DfaMemoryState> initialStates = createInitialStates(psiBlock, visitor, true);
|
||||
if (initialStates == null) {
|
||||
return RunnerResult.NOT_APPLICABLE;
|
||||
}
|
||||
if (initialStates.isEmpty()) {
|
||||
return RunnerResult.OK;
|
||||
}
|
||||
return analyzeMethod(psiBlock, visitor, false, initialStates);
|
||||
}
|
||||
|
||||
public final RunnerResult analyzeCodeBlock(@NotNull PsiCodeBlock block,
|
||||
@NotNull InstructionVisitor visitor,
|
||||
Consumer<DfaMemoryState> initialStateAdjuster) {
|
||||
@@ -243,6 +277,28 @@ public class DataFlowRunner {
|
||||
}
|
||||
}
|
||||
|
||||
public RunnerResult analyzeMethodRecursively(PsiElement block, StandardInstructionVisitor visitor) {
|
||||
Collection<DfaMemoryState> states = createInitialStates(block, visitor, false);
|
||||
if (states == null) return RunnerResult.NOT_APPLICABLE;
|
||||
return analyzeBlockRecursively(block, states, visitor);
|
||||
}
|
||||
|
||||
private RunnerResult analyzeBlockRecursively(PsiElement block,
|
||||
Collection<? extends DfaMemoryState> states,
|
||||
StandardInstructionVisitor visitor) {
|
||||
RunnerResult result = analyzeMethod(block, visitor, false, states);
|
||||
if (result != RunnerResult.OK) return result;
|
||||
|
||||
Ref<RunnerResult> ref = Ref.create(RunnerResult.OK);
|
||||
forNestedClosures((closure, nestedStates) -> {
|
||||
RunnerResult res = analyzeBlockRecursively(closure, nestedStates, visitor);
|
||||
if (res != RunnerResult.OK) {
|
||||
ref.set(res);
|
||||
}
|
||||
});
|
||||
return ref.get();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static DfaValue makeInitialValue(DfaVariableValue var, PsiElement block) {
|
||||
if(var.getQualifier() != null) return null;
|
||||
@@ -372,9 +428,25 @@ public class DataFlowRunner {
|
||||
return myInstructions[index];
|
||||
}
|
||||
|
||||
@NotNull
|
||||
MultiMap<PsiElement, DfaMemoryState> getNestedClosures() {
|
||||
return new MultiMap<>(myNestedClosures);
|
||||
public void forNestedClosures(BiConsumer<PsiElement, Collection<? extends DfaMemoryState>> consumer) {
|
||||
// Copy to avoid concurrent modifications
|
||||
MultiMap<PsiElement, DfaMemoryState> closures = new MultiMap<>(myNestedClosures);
|
||||
for (PsiElement closure : closures.keySet()) {
|
||||
List<DfaVariableValue> unusedVars = StreamEx.of(getFactory().getValues())
|
||||
.select(DfaVariableValue.class)
|
||||
.filter(var -> var.getQualifier() == null)
|
||||
.filter(var -> var.getPsiVariable() instanceof PsiVariable &&
|
||||
!VariableAccessUtils.variableIsUsed((PsiVariable)var.getPsiVariable(), closure))
|
||||
.toList();
|
||||
Collection<? extends DfaMemoryState> states = closures.get(closure);
|
||||
if (!unusedVars.isEmpty()) {
|
||||
List<DfaMemoryStateImpl> stateList = StreamEx.of(states)
|
||||
.peek(state -> unusedVars.forEach(state::flushVariable))
|
||||
.map(state -> (DfaMemoryStateImpl)state).distinct().toList();
|
||||
states = StateQueue.mergeGroup(stateList);
|
||||
}
|
||||
consumer.accept(closure, states);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+49
-28
@@ -24,10 +24,7 @@ import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.UnorderedPair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import com.intellij.psi.PsiPrimitiveType;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.PsiVariable;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
@@ -39,6 +36,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
|
||||
public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
@@ -106,7 +104,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
public DfaMemoryStateImpl createClosureState() {
|
||||
DfaMemoryStateImpl copy = createCopy();
|
||||
copy.flushFields();
|
||||
Set<DfaVariableValue> vars = new HashSet<>(copy.getVariableStates().keySet());
|
||||
Set<DfaVariableValue> vars = new HashSet<>(copy.myVariableStates.keySet());
|
||||
for (DfaVariableValue value : vars) {
|
||||
copy.flushDependencies(value);
|
||||
}
|
||||
@@ -275,10 +273,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
}
|
||||
}
|
||||
|
||||
if (getVariableState(var).isNotNull()) {
|
||||
DfaConstValue dfaNull = myFactory.getConstFactory().getNull();
|
||||
applyRelation(var, dfaNull, true);
|
||||
}
|
||||
updateEqClassesByState(var);
|
||||
}
|
||||
|
||||
private DfaValue handleFlush(DfaVariableValue flushed, DfaValue value) {
|
||||
@@ -733,6 +728,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
return false;
|
||||
}
|
||||
setVariableState((DfaVariableValue)value, newState);
|
||||
updateEquivalentVariables((DfaVariableValue)value, newState);
|
||||
return updateEqClassesByState((DfaVariableValue)value);
|
||||
}
|
||||
return true;
|
||||
@@ -757,6 +753,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
DfaVariableState newState = state.intersectFact(factType, factValue);
|
||||
if (newState == null) return false;
|
||||
setVariableState(var, newState);
|
||||
updateEquivalentVariables(var, newState);
|
||||
return updateEqClassesByState(var);
|
||||
}
|
||||
}
|
||||
@@ -897,19 +894,26 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
}
|
||||
|
||||
private void updateVarStateOnComparison(@NotNull DfaVariableValue dfaVar, DfaValue value) {
|
||||
if (!isUnknownState(dfaVar)) {
|
||||
if (!isUnknownState(dfaVar) && !(dfaVar.getVariableType() instanceof PsiPrimitiveType)) {
|
||||
if (value instanceof DfaConstValue) {
|
||||
Object constValue = ((DfaConstValue)value).getValue();
|
||||
if (constValue == null) {
|
||||
setVariableState(dfaVar, getVariableState(dfaVar).withFact(DfaFactType.CAN_BE_NULL, true));
|
||||
return;
|
||||
}
|
||||
PsiType psiType;
|
||||
if (constValue instanceof PsiVariable) {
|
||||
DfaPsiType dfaType = myFactory.createDfaType(((PsiVariable)constValue).getType());
|
||||
DfaVariableState state = getVariableState(dfaVar).withInstanceofValue(dfaType);
|
||||
if (state != null) {
|
||||
setVariableState(dfaVar, state);
|
||||
}
|
||||
psiType = ((PsiVariable)constValue).getType();
|
||||
}
|
||||
else {
|
||||
PsiModifierListOwner context = dfaVar.getPsiVariable();
|
||||
psiType = JavaPsiFacade.getElementFactory(context.getProject())
|
||||
.createTypeByFQClassName(constValue.getClass().getName(), context.getResolveScope());
|
||||
}
|
||||
DfaPsiType dfaType = myFactory.createDfaType(psiType);
|
||||
DfaVariableState state = getVariableState(dfaVar).withInstanceofValue(dfaType);
|
||||
if (state != null) {
|
||||
setVariableState(dfaVar, state);
|
||||
}
|
||||
}
|
||||
if (isNotNull(value) && !isNotNull(dfaVar)) {
|
||||
@@ -926,12 +930,12 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
}
|
||||
|
||||
final boolean containsCalls = dfaLeft instanceof DfaVariableValue && ((DfaVariableValue)dfaLeft).containsCalls();
|
||||
|
||||
|
||||
// track "x" property state only inside "if (getX() != null) ..."
|
||||
if (containsCalls && !isNotNull(dfaLeft) && isNull(dfaRight) && !isNegated) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (dfaLeft == dfaRight) {
|
||||
return containsCalls || !isNegated;
|
||||
}
|
||||
@@ -1162,6 +1166,17 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
myCachedHash = null;
|
||||
}
|
||||
|
||||
protected void updateEquivalentVariables(DfaVariableValue dfaVar, DfaVariableState state) {
|
||||
int index = getEqClassIndex(dfaVar);
|
||||
if (index != -1) {
|
||||
for (DfaValue value : myEqClasses.get(index).getMemberValues()) {
|
||||
if (value != dfaVar && value instanceof DfaVariableValue) {
|
||||
setVariableState((DfaVariableValue)value, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private StreamEx<DfaVariableValue> equivalentVariables(DfaVariableValue var) {
|
||||
DfaVariableValue qualifier = var.getQualifier();
|
||||
@@ -1206,9 +1221,8 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
return state;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
Map<DfaVariableValue, DfaVariableState> getVariableStates() {
|
||||
return myVariableStates;
|
||||
void forVariableStates(BiConsumer<DfaVariableValue, DfaVariableState> consumer) {
|
||||
myVariableStates.forEach(consumer);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -1282,12 +1296,26 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
void doFlush(@NotNull DfaVariableValue varPlain, boolean markUnknown) {
|
||||
DfaVariableValue varNegated = varPlain.getNegatedValue();
|
||||
|
||||
removeEquivalenceRelations(varPlain);
|
||||
myVariableStates.remove(varPlain);
|
||||
if (varNegated != null) {
|
||||
myVariableStates.remove(varNegated);
|
||||
}
|
||||
if (markUnknown) {
|
||||
myUnknownVariables.add(varPlain);
|
||||
}
|
||||
myCachedHash = null;
|
||||
}
|
||||
|
||||
void removeEquivalenceRelations(@NotNull DfaVariableValue varPlain) {
|
||||
DfaVariableValue varNegated = varPlain.getNegatedValue();
|
||||
final int idPlain = varPlain.getID();
|
||||
final int idNegated = varNegated == null ? -1 : varNegated.getID();
|
||||
|
||||
int[] classes = myIdToEqClassesIndices.get(idPlain);
|
||||
int[] negatedClasses = myIdToEqClassesIndices.get(idNegated);
|
||||
int[] result = ArrayUtil.mergeArrays(ObjectUtils.notNull(classes, ArrayUtil.EMPTY_INT_ARRAY), ObjectUtils.notNull(negatedClasses, ArrayUtil.EMPTY_INT_ARRAY));
|
||||
int[] result = ArrayUtil
|
||||
.mergeArrays(ObjectUtils.notNull(classes, ArrayUtil.EMPTY_INT_ARRAY), ObjectUtils.notNull(negatedClasses, ArrayUtil.EMPTY_INT_ARRAY));
|
||||
|
||||
int interruptCount = 0;
|
||||
|
||||
@@ -1332,13 +1360,6 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
removeAllFromMap(idPlain);
|
||||
removeAllFromMap(idNegated);
|
||||
checkInvariants();
|
||||
myVariableStates.remove(varPlain);
|
||||
if (varNegated != null) {
|
||||
myVariableStates.remove(varNegated);
|
||||
}
|
||||
if (markUnknown) {
|
||||
myUnknownVariables.add(varPlain);
|
||||
}
|
||||
myCachedNonTrivialEqClasses = null;
|
||||
myCachedDistinctClassPairs = null;
|
||||
myCachedHash = null;
|
||||
|
||||
@@ -324,10 +324,8 @@ public class DfaUtil {
|
||||
PsiExpression place = instruction.getPlace();
|
||||
if (place != null) {
|
||||
PlaceResult result = myResults.computeIfAbsent(place, __ -> new PlaceResult());
|
||||
final Map<DfaVariableValue,DfaVariableState> map = ((ValuableDataFlowRunner.MyDfaMemoryState)memState).getVariableStates();
|
||||
for (Map.Entry<DfaVariableValue, DfaVariableState> entry : map.entrySet()) {
|
||||
ValuableDataFlowRunner.ValuableDfaVariableState state = (ValuableDataFlowRunner.ValuableDfaVariableState)entry.getValue();
|
||||
DfaVariableValue variableValue = entry.getKey();
|
||||
((ValuableDataFlowRunner.MyDfaMemoryState)memState).forVariableStates((variableValue, value) -> {
|
||||
ValuableDataFlowRunner.ValuableDfaVariableState state = (ValuableDataFlowRunner.ValuableDfaVariableState)value;
|
||||
final FList<PsiExpression> concatenation = state.myConcatenation;
|
||||
if (!concatenation.isEmpty() && variableValue.getQualifier() == null) {
|
||||
PsiModifierListOwner element = variableValue.getPsiVariable();
|
||||
@@ -335,7 +333,7 @@ public class DfaUtil {
|
||||
result.myValues.put((PsiVariable)element, concatenation);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
DfaValue value = instruction.getValue();
|
||||
if (value instanceof DfaVariableValue && ((DfaVariableValue)value).getQualifier() == null) {
|
||||
PsiModifierListOwner element = ((DfaVariableValue)value).getPsiVariable();
|
||||
|
||||
@@ -265,8 +265,7 @@ class StateMerger {
|
||||
Map<DfaVariableValue, Map<LongRangeSet, LongRangeSet>> ranges = new LinkedHashMap<>();
|
||||
for (DfaMemoryStateImpl state : states) {
|
||||
ProgressManager.checkCanceled();
|
||||
Map<DfaVariableValue, DfaVariableState> variableStates = state.getVariableStates();
|
||||
variableStates.forEach((varValue, varState) -> {
|
||||
state.forVariableStates((varValue, varState) -> {
|
||||
LongRangeSet range = varState.getFact(RANGE);
|
||||
if (range != null) {
|
||||
ranges.computeIfAbsent(varValue, k -> new HashMap<>()).put(range, range);
|
||||
@@ -378,12 +377,12 @@ class StateMerger {
|
||||
|
||||
@NotNull
|
||||
private Set<Fact> getFacts(@NotNull DfaMemoryStateImpl state) {
|
||||
Set<Fact> result = myFacts.get(state);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = ContainerUtil.newLinkedHashSet();
|
||||
return myFacts.computeIfAbsent(state, StateMerger::doGetFacts);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<Fact> doGetFacts(DfaMemoryStateImpl state) {
|
||||
Set<Fact> result = ContainerUtil.newLinkedHashSet();
|
||||
|
||||
IdentityHashMap<EqClass, EqClassInfo> classInfo = new IdentityHashMap<>();
|
||||
|
||||
@@ -426,10 +425,7 @@ class StateMerger {
|
||||
}
|
||||
}
|
||||
|
||||
Map<DfaVariableValue, DfaVariableState> states = state.getVariableStates();
|
||||
for (Map.Entry<DfaVariableValue, DfaVariableState> entry : states.entrySet()) {
|
||||
DfaVariableValue var = entry.getKey();
|
||||
DfaVariableState variableState = entry.getValue();
|
||||
state.forVariableStates((var, variableState) -> {
|
||||
TypeConstraint typeConstraint = variableState.getTypeConstraint();
|
||||
for (DfaPsiType type : typeConstraint.getInstanceofValues()) {
|
||||
result.add(new InstanceofFact(var, true, type));
|
||||
@@ -437,9 +433,7 @@ class StateMerger {
|
||||
for (DfaPsiType type : typeConstraint.getNotInstanceofValues()) {
|
||||
result.add(new InstanceofFact(var, false, type));
|
||||
}
|
||||
}
|
||||
|
||||
myFacts.put(state, result);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -519,9 +513,7 @@ class StateMerger {
|
||||
|
||||
@Override
|
||||
void removeFromState(@NotNull DfaMemoryStateImpl state) {
|
||||
DfaVariableState varState = state.getVariableState(myVar);
|
||||
state.flushVariable(myVar);
|
||||
state.setVariableState(myVar, varState);
|
||||
state.removeEquivalenceRelations(myVar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -162,7 +162,7 @@ public final class TypeConstraint {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
TypeConstraint union(@NotNull TypeConstraint other) {
|
||||
public TypeConstraint union(@NotNull TypeConstraint other) {
|
||||
if(isSuperStateOf(other)) return this;
|
||||
if(other.isSuperStateOf(this)) return other;
|
||||
Set<DfaPsiType> leftTypes = new HashSet<>(this.myInstanceofValues);
|
||||
|
||||
+16
-10
@@ -18,28 +18,34 @@ package com.intellij.codeInspection.dataFlow.value;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.psi.PsiType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class DfaInstanceofValue extends DfaValue {
|
||||
private final PsiExpression myExpression;
|
||||
private final PsiType myCastType;
|
||||
private final @NotNull PsiExpression myExpression;
|
||||
private final @NotNull PsiType myCastType;
|
||||
private final boolean myNegated;
|
||||
private final @NotNull DfaValue myRelation;
|
||||
|
||||
public DfaInstanceofValue(DfaValueFactory factory, PsiExpression expression, PsiType castType) {
|
||||
this(factory, expression, castType, false);
|
||||
}
|
||||
|
||||
public DfaInstanceofValue(DfaValueFactory factory, PsiExpression expression, PsiType castType, boolean negated) {
|
||||
public DfaInstanceofValue(DfaValueFactory factory,
|
||||
@NotNull PsiExpression expression,
|
||||
@NotNull PsiType castType,
|
||||
@NotNull DfaValue relation,
|
||||
boolean negated) {
|
||||
super(factory);
|
||||
myExpression = expression;
|
||||
myCastType = castType;
|
||||
myRelation = relation;
|
||||
myNegated = negated;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
public DfaValue getRelation() {
|
||||
return myRelation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiExpression getExpression() {
|
||||
return myExpression;
|
||||
}
|
||||
@@ -55,6 +61,6 @@ public class DfaInstanceofValue extends DfaValue {
|
||||
|
||||
@Override
|
||||
public DfaValue createNegated() {
|
||||
return new DfaInstanceofValue(myFactory, myExpression, myCastType, !myNegated);
|
||||
return new DfaInstanceofValue(myFactory, myExpression, myCastType, myRelation.createNegated(), !myNegated);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -49,7 +49,7 @@ public class SameParameterValueInspectionBase extends GlobalJavaBatchInspectionT
|
||||
if (value != null) {
|
||||
if (!globalContext.shouldCheck(refParameter, this)) continue;
|
||||
if (problems == null) problems = new ArrayList<>(1);
|
||||
problems.add(registerProblem(manager, refParameter.getElement(), value));
|
||||
problems.add(registerProblem(manager, refParameter.getElement(), value, refParameter.isUsedForWriting()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -228,7 +228,7 @@ public class SameParameterValueInspectionBase extends GlobalJavaBatchInspectionT
|
||||
for (int i = 0, length = paramValues.length; i < length; i++) {
|
||||
String value = paramValues[i];
|
||||
if (value != null && value != NOT_CONST) {
|
||||
holder.registerProblem(registerProblem(holder.getManager(), parameters[i], value));
|
||||
holder.registerProblem(registerProblem(holder.getManager(), parameters[i], value, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -243,13 +243,14 @@ public class SameParameterValueInspectionBase extends GlobalJavaBatchInspectionT
|
||||
|
||||
private ProblemDescriptor registerProblem(@NotNull InspectionManager manager,
|
||||
PsiParameter parameter,
|
||||
String value) {
|
||||
String value,
|
||||
boolean usedForWriting) {
|
||||
final String name = parameter.getName();
|
||||
return manager.createProblemDescriptor(ObjectUtils.notNull(parameter.getNameIdentifier(), parameter),
|
||||
InspectionsBundle.message("inspection.same.parameter.problem.descriptor",
|
||||
"<code>" + name + "</code>",
|
||||
"<code>" + StringUtil.unquoteString(value) + "</code>"),
|
||||
createFix(name, value),
|
||||
usedForWriting ? null : createFix(name, value),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, false);
|
||||
}
|
||||
}
|
||||
|
||||
+17
-34
@@ -343,9 +343,6 @@ public class DuplicatesFinder {
|
||||
}
|
||||
}
|
||||
|
||||
Boolean matchedExtractablePart = matchExtractableExpression(pattern, candidate, candidates, match, false);
|
||||
if (matchedExtractablePart != null) return matchedExtractablePart;
|
||||
|
||||
if (!canBeEquivalent(pattern, candidate)) return false; // Q : is it correct to check implementation classes?
|
||||
|
||||
if (pattern instanceof PsiExpressionList && candidate instanceof PsiExpressionList) { //check varargs
|
||||
@@ -562,9 +559,9 @@ public class DuplicatesFinder {
|
||||
for (int i = 0; i < children1.length; i++) {
|
||||
PsiElement child1 = children1[i];
|
||||
PsiElement child2 = children2[i];
|
||||
if (!matchPattern(child1, child2, candidates, match)) {
|
||||
matchedExtractablePart = matchExtractableExpression(child1, child2, candidates, match, true);
|
||||
if (matchedExtractablePart == null || !matchedExtractablePart) return false;
|
||||
if (!matchPattern(child1, child2, candidates, match) &&
|
||||
!matchExtractableExpression(child1, child2, candidates, match)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,49 +575,35 @@ public class DuplicatesFinder {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Boolean matchExtractableExpression(PsiElement pattern, PsiElement candidate,
|
||||
List<PsiElement> candidates, Match match,
|
||||
boolean withFolding) {
|
||||
if (!(pattern instanceof PsiExpression) || !(candidate instanceof PsiExpression) || withFolding && !myWithExtractedParameters) {
|
||||
return null;
|
||||
}
|
||||
if (myPattern.length == 1 && myPattern[0] == pattern || candidates.size() == 1 && candidates.get(0) == candidate) {
|
||||
return null;
|
||||
private boolean matchExtractableExpression(PsiElement pattern, PsiElement candidate,
|
||||
List<PsiElement> candidates, Match match) {
|
||||
if (!myWithExtractedParameters || !(pattern instanceof PsiExpression) || !(candidate instanceof PsiExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ComplexityHolder patternComplexity = null;
|
||||
if (withFolding) {
|
||||
if (myPatternComplexityHolder == null) {
|
||||
myPatternComplexityHolder = new ComplexityHolder(myPatternAsList);
|
||||
}
|
||||
patternComplexity = myPatternComplexityHolder;
|
||||
if (myPatternComplexityHolder == null) {
|
||||
myPatternComplexityHolder = new ComplexityHolder(myPatternAsList);
|
||||
}
|
||||
ExtractableExpressionPart patternPart = ExtractableExpressionPart.match((PsiExpression)pattern, myPatternAsList, patternComplexity);
|
||||
ExtractableExpressionPart patternPart = ExtractableExpressionPart.match((PsiExpression)pattern, myPatternAsList, myPatternComplexityHolder);
|
||||
if (patternPart == null) {
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
ComplexityHolder candidatesComplexity = null;
|
||||
if (withFolding) {
|
||||
if (myCandidateComplexityHolder == null || myCandidateComplexityHolder.getScope() != candidates) {
|
||||
myCandidateComplexityHolder = new ComplexityHolder(candidates);
|
||||
}
|
||||
candidatesComplexity = myCandidateComplexityHolder;
|
||||
if (myCandidateComplexityHolder == null || myCandidateComplexityHolder.getScope() != candidates) {
|
||||
myCandidateComplexityHolder = new ComplexityHolder(candidates);
|
||||
}
|
||||
ExtractableExpressionPart candidatePart = ExtractableExpressionPart.match((PsiExpression)candidate, candidates, candidatesComplexity);
|
||||
ExtractableExpressionPart candidatePart = ExtractableExpressionPart.match((PsiExpression)candidate, candidates, myCandidateComplexityHolder);
|
||||
if (candidatePart == null) {
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (patternPart.myValue != null && patternPart.myValue.equals(candidatePart.myValue)) {
|
||||
return true;
|
||||
}
|
||||
if (patternPart.myVariable == null || candidatePart.myVariable == null) {
|
||||
return myWithExtractedParameters &&
|
||||
match.putExtractedParameter(patternPart, candidatePart);
|
||||
return match.putExtractedParameter(patternPart, candidatePart);
|
||||
}
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean matchExtractableVariable(PsiElement pattern, PsiElement candidate, Match match) {
|
||||
|
||||
+31
@@ -17,6 +17,7 @@ package com.intellij.refactoring.util.duplicates;
|
||||
|
||||
import com.intellij.codeInsight.JavaPsiEquivalenceUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -94,6 +95,11 @@ public class ExtractableExpressionPart {
|
||||
return matchConstant(expression);
|
||||
}
|
||||
}
|
||||
PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent());
|
||||
if (parent instanceof PsiExpressionStatement ||
|
||||
parent instanceof PsiExpressionList && parent.getParent() instanceof PsiExpressionListStatement) {
|
||||
return null;
|
||||
}
|
||||
if (complexityHolder != null && (isConstant || complexityHolder.isAcceptableExpression(expression))) {
|
||||
return matchExpression(expression);
|
||||
}
|
||||
@@ -116,6 +122,9 @@ public class ExtractableExpressionPart {
|
||||
@Nullable
|
||||
static ExtractableExpressionPart matchVariable(@NotNull PsiReferenceExpression expression, @Nullable List<PsiElement> scope) {
|
||||
PsiElement resolved = expression.resolve();
|
||||
if (resolved instanceof PsiField && isUnqualifiedModification(expression)) {
|
||||
return null;
|
||||
}
|
||||
if (resolved instanceof PsiVariable && (scope == null || !DuplicatesFinder.isUnder(resolved, scope))) {
|
||||
PsiVariable variable = (PsiVariable)resolved;
|
||||
return new ExtractableExpressionPart(expression, variable, null, variable.getType());
|
||||
@@ -123,6 +132,28 @@ public class ExtractableExpressionPart {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isUnqualifiedModification(@NotNull PsiReferenceExpression expression) {
|
||||
PsiExpression qualifier = expression.getQualifierExpression();
|
||||
if (qualifier == null || qualifier instanceof PsiQualifiedExpression) { // 'this.' and 'super.' with fields are just like unqualified
|
||||
PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent());
|
||||
if (parent instanceof PsiAssignmentExpression) {
|
||||
PsiAssignmentExpression assignment = (PsiAssignmentExpression)parent;
|
||||
if (PsiTreeUtil.isAncestor(assignment.getLExpression(), expression, false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (parent instanceof PsiUnaryExpression) {
|
||||
PsiUnaryExpression unary = (PsiUnaryExpression)parent;
|
||||
IElementType tokenType = unary.getOperationTokenType();
|
||||
if ((tokenType.equals(JavaTokenType.PLUSPLUS) || tokenType.equals(JavaTokenType.MINUSMINUS)) &&
|
||||
PsiTreeUtil.isAncestor(unary.getOperand(), expression, false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ExtractableExpressionPart matchExpression(@NotNull PsiExpression expression) {
|
||||
PsiType type = expression.getType();
|
||||
|
||||
-13
@@ -50,12 +50,6 @@ public class ExtractedParameter {
|
||||
if (type == null) {
|
||||
return false;
|
||||
}
|
||||
if (patternPart.myVariable != null && !isStaticOrLocal(patternPart.myVariable)) {
|
||||
return false;
|
||||
}
|
||||
if (candidatePart.myVariable != null && !isStaticOrLocal(candidatePart.myVariable)) {
|
||||
return false;
|
||||
}
|
||||
for (ExtractedParameter parameter : parameters) {
|
||||
boolean samePattern = parameter.samePattern(patternPart);
|
||||
boolean sameCandidate = parameter.sameCandidate(candidatePart);
|
||||
@@ -141,13 +135,6 @@ public class ExtractedParameter {
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean isStaticOrLocal(@NotNull PsiVariable variable) {
|
||||
if (variable instanceof PsiField && variable.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return true;
|
||||
}
|
||||
return variable instanceof PsiLocalVariable || variable instanceof PsiParameter;
|
||||
}
|
||||
|
||||
private static class FieldModificationVisitor extends JavaRecursiveElementWalkingVisitor {
|
||||
private final Set<PsiField> myFields;
|
||||
private boolean myModified;
|
||||
|
||||
@@ -213,8 +213,8 @@
|
||||
<usageContextPanelProvider implementation="com.intellij.usageView.UsageContextDataflowFromPanel$Provider"/>
|
||||
<usageContextPanelProvider implementation="com.intellij.usageView.UsageContextDataflowToPanel$Provider"/>
|
||||
<usageTypeProvider implementation="com.intellij.usages.impl.rules.JavaUsageTypeProvider"/>
|
||||
<fileStructureGroupRuleProvider implementation="com.intellij.usages.impl.rules.JavaMethodGroupRuleProvider"/>
|
||||
<fileStructureGroupRuleProvider implementation="com.intellij.usages.impl.rules.JavaClassGroupRuleProvider"/>
|
||||
<fileStructureGroupRuleProvider implementation="com.intellij.usages.impl.rules.JavaMethodGroupRuleProvider"/>
|
||||
<fileStructureGroupRuleProvider implementation="com.intellij.usages.impl.rules.NonJavaFileGroupRuleProvider"/>
|
||||
<qualifiedNameProvider implementation="com.intellij.ide.actions.JavaQualifiedNameProvider"/>
|
||||
<referenceImporter implementation="com.intellij.codeInsight.daemon.impl.JavaReferenceImporter"/>
|
||||
@@ -236,8 +236,8 @@
|
||||
<renamePsiElementProcessor implementation="com.intellij.refactoring.rename.RenameJavaClassProcessor"/>
|
||||
<renamePsiElementProcessor implementation="com.intellij.refactoring.rename.RenameJavaMethodProcessor" id="javamethod"/>
|
||||
<renamePsiElementProcessor implementation="com.intellij.refactoring.rename.RenameJavaVariableProcessor" id="javaVariable"/>
|
||||
<renamePsiElementProcessor implementation="com.intellij.refactoring.rename.RenameAliasingPomTargetProcessor"/>
|
||||
<renamePsiElementProcessor implementation="com.intellij.refactoring.rename.RenameJavaModuleProcessor"/>
|
||||
<renamePsiElementProcessor implementation="com.intellij.refactoring.rename.RenameAliasingPomTargetProcessor"/>
|
||||
<referenceProviderType key="Class Reference Provider"
|
||||
implementationClass="com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReferenceProvider"/>
|
||||
<findUsagesHandlerFactory implementation="com.intellij.find.findUsages.JavaFindUsagesHandlerFactory" id="java"
|
||||
|
||||
@@ -404,7 +404,7 @@ public class JavaCompletionUtil {
|
||||
}
|
||||
}
|
||||
|
||||
return containsMember(castType, o) && !containsMember(plainQualifier, o);
|
||||
return containsMember(castType, o, true) && !containsMember(plainQualifier, o, true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -469,7 +469,7 @@ public class JavaCompletionUtil {
|
||||
}
|
||||
}), -1);
|
||||
}
|
||||
if (containsMember(qualifierType, object) && !qualifierType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
|
||||
if (containsMember(qualifierType, object, false) && !qualifierType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
|
||||
LookupElementDecorator<LookupElement> bold = LookupElementDecorator.withRenderer(item, new LookupElementRenderer<LookupElementDecorator<LookupElement>>() {
|
||||
@Override
|
||||
public void renderElement(LookupElementDecorator<LookupElement> element, LookupElementPresentation presentation) {
|
||||
@@ -495,9 +495,11 @@ public class JavaCompletionUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Contract("null, _ -> false")
|
||||
public static boolean containsMember(@Nullable PsiType qualifierType, @NotNull Object object) {
|
||||
if (qualifierType instanceof PsiArrayType && object instanceof PsiMember) { //length and clone()
|
||||
@Contract("null, _, _ -> false")
|
||||
private static boolean containsMember(@Nullable PsiType qualifierType, @NotNull Object object, boolean checkBases) {
|
||||
if (!(object instanceof PsiMember)) return false;
|
||||
|
||||
if (qualifierType instanceof PsiArrayType) { //length and clone()
|
||||
PsiFile file = ((PsiMember)object).getContainingFile();
|
||||
if (file == null || file.getVirtualFile() == null) { //yes, they're a bit dummy
|
||||
return true;
|
||||
@@ -506,12 +508,11 @@ public class JavaCompletionUtil {
|
||||
else if (qualifierType instanceof PsiClassType) {
|
||||
PsiClass qualifierClass = ((PsiClassType)qualifierType).resolve();
|
||||
if (qualifierClass == null) return false;
|
||||
if (object instanceof PsiMethod && qualifierClass.findMethodBySignature((PsiMethod)object, false) != null) {
|
||||
if (object instanceof PsiMethod && qualifierClass.findMethodBySignature((PsiMethod)object, checkBases) != null) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof PsiMember) {
|
||||
return qualifierClass.equals(((PsiMember)object).getContainingClass());
|
||||
}
|
||||
PsiClass memberClass = ((PsiMember)object).getContainingClass();
|
||||
return checkBases ? InheritanceUtil.isInheritorOrSelf(qualifierClass, memberClass, true) : qualifierClass.equals(memberClass);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
+3
-1
@@ -49,7 +49,9 @@ public class CreateCastExpressionFromInstanceofAction extends CreateLocalVarFrom
|
||||
assert instanceOfExpression.getContainingFile() == file : instanceOfExpression.getContainingFile() + "; file="+file;
|
||||
PsiElement decl = createAndInsertCast(instanceOfExpression, editor, file);
|
||||
if (decl == null) return;
|
||||
decl = CodeStyleManager.getInstance(project).reformat(CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(decl));
|
||||
decl = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(decl);
|
||||
if (decl == null) return;
|
||||
decl = CodeStyleManager.getInstance(project).reformat(decl);
|
||||
editor.getCaretModel().moveToOffset(decl.getTextRange().getEndOffset());
|
||||
}
|
||||
|
||||
|
||||
+9
-2
@@ -28,6 +28,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor;
|
||||
import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor;
|
||||
import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
|
||||
@@ -135,6 +136,14 @@ public class SameParameterValueInspection extends SameParameterValueInspectionBa
|
||||
public static void inlineSameParameterValue(final PsiMethod method, final PsiParameter parameter, final PsiExpression defToInline) {
|
||||
final MultiMap<PsiElement, String> conflicts = new MultiMap<>();
|
||||
JavaSafeDeleteProcessor.collectMethodConflicts(conflicts, method, parameter);
|
||||
final Collection<PsiReference> refsToInline = ReferencesSearch.search(parameter).findAll();
|
||||
for (PsiReference reference : refsToInline) {
|
||||
PsiElement referenceElement = reference.getElement();
|
||||
if (referenceElement instanceof PsiExpression && PsiUtil.isAccessedForWriting((PsiExpression)referenceElement)) {
|
||||
conflicts.putValue(referenceElement, "Parameter has write usages. Inline is not supported");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!conflicts.isEmpty()) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
if (!BaseRefactoringProcessor.ConflictsInTestsException.isTestIgnore()) {
|
||||
@@ -146,8 +155,6 @@ public class SameParameterValueInspection extends SameParameterValueInspectionBa
|
||||
}
|
||||
}
|
||||
|
||||
final Collection<PsiReference> refsToInline = ReferencesSearch.search(parameter).findAll();
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(() -> {
|
||||
try {
|
||||
PsiExpression[] exprs = new PsiExpression[refsToInline.size()];
|
||||
|
||||
+18
-4
@@ -33,6 +33,7 @@ import com.intellij.util.IJSwingUtilities;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -132,7 +133,14 @@ public abstract class BaseConvertToLocalQuickFix<V extends PsiVariable> implemen
|
||||
variable,
|
||||
references,
|
||||
delete,
|
||||
declaration -> anchorBlock.addBefore(declaration, anchor)
|
||||
declaration -> {
|
||||
PsiElement parent = anchorBlock.getParent();
|
||||
if (parent instanceof PsiSwitchStatement) {
|
||||
PsiElement switchContainer = parent.getParent();
|
||||
return switchContainer.addBefore(declaration, parent);
|
||||
}
|
||||
return anchorBlock.addBefore(declaration, anchor);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -147,14 +155,20 @@ public abstract class BaseConvertToLocalQuickFix<V extends PsiVariable> implemen
|
||||
return WriteAction.compute(() -> {
|
||||
final PsiElement newDeclaration = moveDeclaration(elementFactory, localName, variable, initializer, action, references);
|
||||
if (delete) {
|
||||
beforeDelete(project, variable, newDeclaration);
|
||||
variable.normalizeDeclaration();
|
||||
variable.delete();
|
||||
deleteSourceVariable(project, variable, newDeclaration);
|
||||
}
|
||||
return newDeclaration;
|
||||
});
|
||||
}
|
||||
|
||||
protected void deleteSourceVariable(@NotNull Project project, @NotNull V variable, PsiElement newDeclaration) {
|
||||
CommentTracker tracker = new CommentTracker();
|
||||
beforeDelete(project, variable, newDeclaration);
|
||||
variable.normalizeDeclaration();
|
||||
tracker.delete(variable);
|
||||
tracker.insertCommentsBefore(newDeclaration);
|
||||
}
|
||||
|
||||
protected PsiElement moveDeclaration(PsiElementFactory elementFactory,
|
||||
String localName,
|
||||
V variable,
|
||||
|
||||
+1
-6
@@ -70,12 +70,7 @@ public class FieldCanBeLocalInspection extends FieldCanBeLocalInspectionBase {
|
||||
}
|
||||
if (element != null) {
|
||||
final PsiElement finalElement = element;
|
||||
Runnable runnable = () -> {
|
||||
beforeDelete(project, variable, finalElement);
|
||||
variable.normalizeDeclaration();
|
||||
variable.delete();
|
||||
};
|
||||
ApplicationManager.getApplication().runWriteAction(runnable);
|
||||
ApplicationManager.getApplication().runWriteAction(() -> deleteSourceVariable(project, variable, finalElement));
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
+4
-3
@@ -19,12 +19,13 @@ import com.intellij.lang.ASTFactory;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.LanguageParserDefinitions;
|
||||
import com.intellij.lang.ParserDefinition;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
|
||||
import com.intellij.psi.impl.source.tree.Factory;
|
||||
import com.intellij.psi.impl.source.tree.LeafElement;
|
||||
@@ -39,14 +40,14 @@ import com.intellij.util.CharTable;
|
||||
public class ShiftIndentInsideHelper {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.codeStyle.Helper");
|
||||
|
||||
private final CodeStyleSettings mySettings;
|
||||
private final CommonCodeStyleSettings mySettings;
|
||||
private final FileType myFileType;
|
||||
private final IndentHelper myIndentIndentHelper;
|
||||
private final Project myProject;
|
||||
|
||||
public ShiftIndentInsideHelper(FileType fileType, Project project) {
|
||||
myProject = project;
|
||||
mySettings = CodeStyleSettingsManager.getSettings(project);
|
||||
mySettings = CodeStyleSettingsManager.getSettings(project).getCommonSettings(JavaLanguage.INSTANCE);
|
||||
myFileType = fileType;
|
||||
myIndentIndentHelper = IndentHelper.getInstance();
|
||||
}
|
||||
|
||||
+4
-1
@@ -204,11 +204,14 @@ public class JavaPushDownDelegate extends PushDownDelegate<MemberInfo, PsiMember
|
||||
refsToRebind.add(reference);
|
||||
}
|
||||
}
|
||||
if (member instanceof PsiField) {
|
||||
((PsiField)member).normalizeDeclaration();
|
||||
}
|
||||
|
||||
member = (PsiMember)member.copy();
|
||||
RefactoringUtil.replaceMovedMemberTypeParameters(member, PsiUtil.typeParametersIterable(sourceClass), substitutor, factory);
|
||||
PsiMember newMember = null;
|
||||
if (member instanceof PsiField) {
|
||||
((PsiField)member).normalizeDeclaration();
|
||||
if (sourceClass.isInterface() && !targetClass.isInterface()) {
|
||||
PsiUtil.setModifierProperty(member, PsiModifier.PUBLIC, true);
|
||||
PsiUtil.setModifierProperty(member, PsiModifier.STATIC, true);
|
||||
|
||||
@@ -367,7 +367,7 @@ public class RefactoringUtil {
|
||||
}
|
||||
ExpectedTypeInfo[] expectedTypes = ExpectedTypesProvider.getExpectedTypes(expr, false);
|
||||
if (expectedTypes.length == 1 || (isFunctionalType || !isDenotable)&& expectedTypes.length > 0 ) {
|
||||
if (typeByExpression != null && Arrays.stream(expectedTypes).anyMatch(typeInfo -> typeInfo.getType().equals(typeByExpression))) {
|
||||
if (typeByExpression != null && Arrays.stream(expectedTypes).anyMatch(typeInfo -> typeByExpression.isAssignableFrom(typeInfo.getType()))) {
|
||||
return type;
|
||||
}
|
||||
type = expectedTypes[0].getType();
|
||||
@@ -889,16 +889,13 @@ public class RefactoringUtil {
|
||||
final PsiElement invalidBody = lambdaExpression.getBody();
|
||||
if (invalidBody == null) return declaration;
|
||||
|
||||
final PsiLambdaExpression expressionFromText = (PsiLambdaExpression)elementFactory
|
||||
.createExpressionFromText(lambdaExpression.getParameterList().getText() + " -> {}", lambdaExpression.getParent());
|
||||
String lambdaParamListWithArrowAndComments = lambdaExpression.getText()
|
||||
.substring(0, (declaration.isPhysical() ? declaration : invalidBody).getStartOffsetInParent());
|
||||
final PsiLambdaExpression expressionFromText = (PsiLambdaExpression)elementFactory.createExpressionFromText(lambdaParamListWithArrowAndComments + "{}", lambdaExpression.getParent());
|
||||
PsiCodeBlock newBody = (PsiCodeBlock)expressionFromText.getBody();
|
||||
LOG.assertTrue(newBody != null);
|
||||
newBody.add(declaration);
|
||||
|
||||
lambdaExpression =
|
||||
(PsiLambdaExpression)lambdaExpression.replace(elementFactory.createExpressionFromText(
|
||||
lambdaExpression.getParameterList().getText() + " -> " + invalidBody.getText(), lambdaExpression));
|
||||
|
||||
final PsiElement lambdaExpressionBody = lambdaExpression.getBody();
|
||||
LOG.assertTrue(lambdaExpressionBody != null);
|
||||
final PsiStatement lastBodyStatement;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.lang.jvm;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a package.
|
||||
*
|
||||
* @see Package
|
||||
*/
|
||||
public interface JvmPackage extends JvmAnnotatedElement, JvmNamedElement {
|
||||
|
||||
/**
|
||||
* @return the name, or {@code null} for the default package
|
||||
*/
|
||||
@Nullable("default package")
|
||||
@Override
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* @return the fully qualified name, or an empty string for the default package
|
||||
*/
|
||||
@NotNull
|
||||
String getQualifiedName();
|
||||
|
||||
/**
|
||||
* @return the parent package, or {@code null} for the default package
|
||||
*/
|
||||
@Nullable
|
||||
JvmPackage getParentPackage();
|
||||
}
|
||||
@@ -1,20 +1,7 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.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.
|
||||
*/
|
||||
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.psi;
|
||||
|
||||
import com.intellij.lang.jvm.JvmPackage;
|
||||
import com.intellij.navigation.NavigationItem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
@@ -24,7 +11,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* Represents a Java package.
|
||||
*/
|
||||
public interface PsiPackage extends PsiCheckedRenameElement, NavigationItem, PsiModifierListOwner, PsiDirectoryContainer, PsiQualifiedNamedElement {
|
||||
public interface PsiPackage extends PsiCheckedRenameElement, NavigationItem, PsiModifierListOwner,
|
||||
PsiDirectoryContainer, PsiQualifiedNamedElement, JvmPackage {
|
||||
|
||||
String PACKAGE_INFO_CLASS = "package-info";
|
||||
String PACKAGE_INFO_FILE = PACKAGE_INFO_CLASS + ".java";
|
||||
String PACKAGE_INFO_CLS_FILE = PACKAGE_INFO_CLASS + ".class";
|
||||
@@ -45,6 +34,7 @@ public interface PsiPackage extends PsiCheckedRenameElement, NavigationItem, Psi
|
||||
*
|
||||
* @return the parent package, or null for the default package.
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
PsiPackage getParentPackage();
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ public class PsiMethodUtil {
|
||||
|
||||
public static final Condition<PsiClass> MAIN_CLASS = psiClass -> {
|
||||
if (psiClass instanceof PsiAnonymousClass) return false;
|
||||
if (psiClass.isAnnotationType()) return false;
|
||||
if (psiClass.isInterface() && !PsiUtil.isLanguageLevel8OrHigher(psiClass)) return false;
|
||||
return psiClass.getContainingClass() == null || psiClass.hasModifierProperty(PsiModifier.STATIC);
|
||||
};
|
||||
|
||||
@@ -10,6 +10,8 @@ import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
|
||||
import com.intellij.psi.impl.java.stubs.PsiJavaModuleStub;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.search.ProjectScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
@@ -159,6 +161,12 @@ public class PsiJavaModuleImpl extends JavaStubPsiElement<PsiJavaModuleStub> imp
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SearchScope getUseScope() {
|
||||
return ProjectScope.getProjectScope(getProject());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PsiJavaModule:" + getName();
|
||||
|
||||
@@ -66,7 +66,8 @@ public class PsiJavaModuleReference extends PsiReferenceBase.Poly<PsiJavaModuleR
|
||||
@NotNull
|
||||
@Override
|
||||
public ResolveResult[] resolve(@NotNull PsiJavaModuleReference reference, boolean incompleteCode) {
|
||||
PsiFile file = reference.getElement().getContainingFile();
|
||||
PsiJavaModuleReferenceElement refElement = reference.getElement();
|
||||
PsiFile file = refElement.getContainingFile();
|
||||
String moduleName = reference.getCanonicalText();
|
||||
|
||||
if (file instanceof PsiJavaFile) {
|
||||
@@ -76,7 +77,8 @@ public class PsiJavaModuleReference extends PsiReferenceBase.Poly<PsiJavaModuleR
|
||||
}
|
||||
}
|
||||
|
||||
Collection<PsiJavaModule> modules = findModules(file, moduleName, incompleteCode);
|
||||
boolean global = incompleteCode || refElement.getParent() instanceof PsiPackageAccessibilityStatement;
|
||||
Collection<PsiJavaModule> modules = findModules(file, moduleName, global);
|
||||
if (!modules.isEmpty()) {
|
||||
ResolveResult[] result = new ResolveResult[modules.size()];
|
||||
int i = 0;
|
||||
@@ -88,9 +90,9 @@ public class PsiJavaModuleReference extends PsiReferenceBase.Poly<PsiJavaModuleR
|
||||
}
|
||||
}
|
||||
|
||||
private static Collection<PsiJavaModule> findModules(PsiFile file, String moduleName, boolean incompleteCode) {
|
||||
private static Collection<PsiJavaModule> findModules(PsiFile file, String moduleName, boolean global) {
|
||||
Project project = file.getProject();
|
||||
GlobalSearchScope scope = incompleteCode ? GlobalSearchScope.allScope(project) : file.getResolveScope();
|
||||
GlobalSearchScope scope = global ? GlobalSearchScope.allScope(project) : file.getResolveScope();
|
||||
return JavaFileManager.getInstance(project).findModules(moduleName, scope);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ public class JavaResolveUtil {
|
||||
PsiClass topAccessClass = getTopLevelClass(accessObjectClass, memberClass);
|
||||
if (!manager.areElementsEquivalent(topMemberClass, topAccessClass)) return false;
|
||||
if (accessObjectClass instanceof PsiAnonymousClass && accessObjectClass.isInheritor(memberClass, true)) {
|
||||
if (place instanceof PsiMethodCallExpression) {
|
||||
if (!(place instanceof PsiAnonymousClass)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.source.resolve;
|
||||
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
class Foo {
|
||||
void test(String s) {
|
||||
Object x;
|
||||
x = s;
|
||||
System.out.println(x.subst<caret>);
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class Foo {
|
||||
void test(String s) {
|
||||
Object x;
|
||||
x = s;
|
||||
System.out.println(((String) x).substring());
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
interface E { }
|
||||
|
||||
interface Named {
|
||||
String getName();
|
||||
}
|
||||
interface MyNamed extends Named {}
|
||||
|
||||
class X {
|
||||
void foo(E e) {
|
||||
if (e instanceof MyNamed && e.getn<caret>)
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
interface E { }
|
||||
|
||||
interface Named {
|
||||
String getName();
|
||||
}
|
||||
interface MyNamed extends Named {}
|
||||
|
||||
class X {
|
||||
void foo(E e) {
|
||||
if (e instanceof MyNamed && ((MyNamed) e).getName()<caret>)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
class Foo {
|
||||
void test(String s) {
|
||||
Object x = s;
|
||||
System.out.println(x.subst<caret>);
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class Foo {
|
||||
void test(String s) {
|
||||
Object x = s;
|
||||
System.out.println(((String) x).substring());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class Foo {
|
||||
void test(Object obj) {
|
||||
if(!(obj instanceof String)) {
|
||||
obj = "foo";
|
||||
}
|
||||
obj.subst<caret>
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class Foo {
|
||||
void test(Object obj) {
|
||||
if(!(obj instanceof String)) {
|
||||
obj = "foo";
|
||||
}
|
||||
((String) obj).substring()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import java.util.*;
|
||||
|
||||
class Foo {
|
||||
void test(Optional<Object> opt) {
|
||||
opt.filter(x -> x instanceof String)
|
||||
.map(s -> s.subst<caret>)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import java.util.*;
|
||||
|
||||
class Foo {
|
||||
void test(Optional<Object> opt) {
|
||||
opt.filter(x -> x instanceof String)
|
||||
.map(s -> ((String) s).substring())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import java.util.*;
|
||||
|
||||
class Foo {
|
||||
void test(List<?> obj) {
|
||||
obj.stream()
|
||||
.filter(x -> x instanceof String)
|
||||
.forEach(e -> e.subst<caret>);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import java.util.*;
|
||||
|
||||
class Foo {
|
||||
void test(List<?> obj) {
|
||||
obj.stream()
|
||||
.filter(x -> x instanceof String)
|
||||
.forEach(e -> ((String) e).substring());
|
||||
}
|
||||
}
|
||||
+2
@@ -3,12 +3,14 @@ enum EnumPrivateMethodTest {
|
||||
@Override
|
||||
public void execute() {
|
||||
this.<error descr="'firstMethod()' has private access in 'EnumPrivateMethodTest'">firstMethod</error>();
|
||||
String s = this.<error descr="'myDescription' has private access in 'EnumPrivateMethodTest'">myDescription</error>;
|
||||
}
|
||||
};
|
||||
|
||||
public abstract void execute();
|
||||
|
||||
private void firstMethod() {}
|
||||
private final String myDescription = "description";
|
||||
}
|
||||
|
||||
abstract class EnumPrivateMethodTest1 {
|
||||
|
||||
+1
@@ -5,6 +5,7 @@ class ITest {
|
||||
|
||||
public IntelliJBugConvertToLocal(int x, int z) {
|
||||
|
||||
//my comment to keep in code
|
||||
ArrayList<String> mayBeLocal = new ArrayList<String>();
|
||||
if (x == 5) {
|
||||
mayBeLocal.add("jjj");
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// "Convert to local" "true"
|
||||
class TestFieldConversion
|
||||
{
|
||||
|
||||
public void someMethod(int s) {
|
||||
int someInt = 0;
|
||||
switch (s) {
|
||||
case 1:
|
||||
System.out.println(someInt);
|
||||
break;
|
||||
case 3:
|
||||
System.out.println(someInt);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -3,7 +3,7 @@ import java.util.ArrayList;
|
||||
|
||||
class ITest {
|
||||
|
||||
private ArrayList<String> may<caret>BeLocal = new ArrayList<String>();
|
||||
private ArrayList<String> may<caret>BeLocal = new ArrayList<String>(); //my comment to keep in code
|
||||
|
||||
public IntelliJBugConvertToLocal(int x, int z) {
|
||||
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// "Convert to local" "true"
|
||||
class TestFieldConversion
|
||||
{
|
||||
private int som<caret>eInt = 0;
|
||||
|
||||
public void someMethod(int s) {
|
||||
switch (s) {
|
||||
case 1:
|
||||
System.out.println(someInt);
|
||||
break;
|
||||
case 3:
|
||||
System.out.println(someInt);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
class NullableReturn {
|
||||
@NotNull Object test(Object o, Object o2, Object o3) {
|
||||
Object x = o == null ? o3 : o2;
|
||||
// no nullable return from notnull method here
|
||||
return x == null ? o3 : x;
|
||||
}
|
||||
}
|
||||
@@ -46,10 +46,17 @@ public class StreamInlining {
|
||||
|
||||
void test2(int[] array) {
|
||||
IntStream.of(array).filter(x -> x < 5)
|
||||
.filter(x -> x > 7) // TODO: find variable state for non-qualified value
|
||||
.filter(x -> <warning descr="Condition 'x > 7' is always 'false'">x > 7</warning>)
|
||||
.forEach(value -> System.out.println(value));
|
||||
}
|
||||
|
||||
void testInstanceof(List<?> objects) {
|
||||
objects.stream()
|
||||
.filter(x -> x instanceof String)
|
||||
.filter(x -> <warning descr="Condition 'x instanceof Number' is always 'false'">x instanceof Number</warning>)
|
||||
.forEach(System.out::println);
|
||||
}
|
||||
|
||||
// IDEA-152871
|
||||
static class A {
|
||||
|
||||
|
||||
@@ -104,3 +104,14 @@ class Example3
|
||||
private long total = 0;
|
||||
}
|
||||
}
|
||||
|
||||
class Example4 {
|
||||
@GuardedBy("this")
|
||||
protected Object field;
|
||||
|
||||
static class Example4Derived extends Example4 {
|
||||
synchronized void foo() {
|
||||
Object o = field;
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "f 1" "true"
|
||||
public class Test {
|
||||
void foo(boolean <caret>f){
|
||||
f++;
|
||||
}
|
||||
void bar(){foo(1);}
|
||||
void bar1(){foo(1);}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import java.util.List;
|
||||
|
||||
class C {
|
||||
List<String> x;
|
||||
List<String> y;
|
||||
|
||||
private void foo() {
|
||||
<selection>
|
||||
if (x.isEmpty()) return;
|
||||
x.remove(0);
|
||||
y.add(str());
|
||||
baz();</selection>
|
||||
}
|
||||
|
||||
private void bar() {
|
||||
if (y.isEmpty()) return;
|
||||
y.remove(0);
|
||||
x.add(str());
|
||||
baz();
|
||||
}
|
||||
|
||||
private void baz() { }
|
||||
private String str() { return null; }
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import java.util.List;
|
||||
|
||||
class C {
|
||||
List<String> x;
|
||||
List<String> y;
|
||||
|
||||
private void foo() {
|
||||
|
||||
newMethod(x, y);
|
||||
}
|
||||
|
||||
private void newMethod(List<String> x, List<String> y) {
|
||||
if (x.isEmpty()) return;
|
||||
x.remove(0);
|
||||
y.add(str());
|
||||
baz();
|
||||
}
|
||||
|
||||
private void bar() {
|
||||
newMethod(y, x);
|
||||
}
|
||||
|
||||
private void baz() { }
|
||||
private String str() { return null; }
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import java.util.List;
|
||||
|
||||
class ArgumentFoldingWholeStatement {
|
||||
List<String> x;
|
||||
List<String> y;
|
||||
|
||||
private void foo() {
|
||||
<selection>x.add(str());
|
||||
baz();</selection>
|
||||
}
|
||||
|
||||
private void bar() {
|
||||
y.add(str());
|
||||
baz();
|
||||
}
|
||||
|
||||
private String str() { return null; }
|
||||
private void baz() { }
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import java.util.List;
|
||||
|
||||
class ArgumentFoldingWholeStatement {
|
||||
List<String> x;
|
||||
List<String> y;
|
||||
|
||||
private void foo() {
|
||||
<selection>
|
||||
for (int i = 0; ++i < 5; x.indexOf(str())) {
|
||||
baz();
|
||||
}</selection>
|
||||
}
|
||||
|
||||
private void bar() {
|
||||
for (int i = 0; ++i < 5; y.indexOf(str())) {
|
||||
baz();
|
||||
}
|
||||
}
|
||||
|
||||
private String str() { return null; }
|
||||
private void baz() { }
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import java.util.List;
|
||||
|
||||
class ArgumentFoldingWholeStatement {
|
||||
List<String> x;
|
||||
List<String> y;
|
||||
|
||||
private void foo() {
|
||||
<selection>
|
||||
for (int i = 0; i < 5; i++, x.indexOf(str())) {
|
||||
baz();
|
||||
}</selection>
|
||||
}
|
||||
|
||||
private void bar() {
|
||||
for (int i = 0; i < 5; i++, y.indexOf(str())) {
|
||||
baz();
|
||||
}
|
||||
}
|
||||
|
||||
private String str() { return null; }
|
||||
private void baz() { }
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import java.util.List;
|
||||
|
||||
class ArgumentFoldingWholeStatement {
|
||||
List<String> x;
|
||||
List<String> y;
|
||||
|
||||
private void foo() {
|
||||
|
||||
newMethod(x);
|
||||
}
|
||||
|
||||
private void newMethod(List<String> x) {
|
||||
for (int i = 0; i < 5; i++, x.indexOf(str())) {
|
||||
baz();
|
||||
}
|
||||
}
|
||||
|
||||
private void bar() {
|
||||
newMethod(y);
|
||||
}
|
||||
|
||||
private String str() { return null; }
|
||||
private void baz() { }
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import java.util.List;
|
||||
|
||||
class ArgumentFoldingWholeStatement {
|
||||
List<String> x;
|
||||
List<String> y;
|
||||
|
||||
private void foo() {
|
||||
|
||||
newMethod(x);
|
||||
}
|
||||
|
||||
private void newMethod(List<String> x) {
|
||||
for (int i = 0; ++i < 5; x.indexOf(str())) {
|
||||
baz();
|
||||
}
|
||||
}
|
||||
|
||||
private void bar() {
|
||||
newMethod(y);
|
||||
}
|
||||
|
||||
private String str() { return null; }
|
||||
private void baz() { }
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import java.util.List;
|
||||
|
||||
class ArgumentFoldingWholeStatement {
|
||||
List<String> x;
|
||||
List<String> y;
|
||||
|
||||
private void foo() {
|
||||
newMethod(x);
|
||||
}
|
||||
|
||||
private void newMethod(List<String> x) {
|
||||
x.add(str());
|
||||
baz();
|
||||
}
|
||||
|
||||
private void bar() {
|
||||
newMethod(y);
|
||||
}
|
||||
|
||||
private String str() { return null; }
|
||||
private void baz() { }
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
class DecrementDifferentFieldsDuplicate {
|
||||
int x;
|
||||
int y;
|
||||
|
||||
private void foo() {
|
||||
<selection>
|
||||
if (x > 0) {
|
||||
bar(x);
|
||||
x--;
|
||||
}</selection>
|
||||
|
||||
if (y > 0) {
|
||||
bar(y);
|
||||
y--;
|
||||
}
|
||||
}
|
||||
|
||||
private void bar(int i) { }
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
class DecrementDifferentFieldsDuplicate {
|
||||
int x;
|
||||
int y;
|
||||
|
||||
private void foo() {
|
||||
|
||||
newMethod();
|
||||
|
||||
if (y > 0) {
|
||||
bar(y);
|
||||
y--;
|
||||
}
|
||||
}
|
||||
|
||||
private void newMethod() {
|
||||
if (x > 0) {
|
||||
bar(x);
|
||||
x--;
|
||||
}
|
||||
}
|
||||
|
||||
private void bar(int i) { }
|
||||
}
|
||||
@@ -1,14 +1,15 @@
|
||||
public class Test {
|
||||
int method() {
|
||||
try {
|
||||
return newMethod("Text", 0);
|
||||
System.out.println("Text");
|
||||
return 0;
|
||||
} finally {
|
||||
return newMethod("!!!", 1);
|
||||
return newMethod();
|
||||
}
|
||||
}
|
||||
|
||||
private int newMethod(String s, int i) {
|
||||
System.out.println(s);
|
||||
return i;
|
||||
private int newMethod() {
|
||||
System.out.println("!!!");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -3,18 +3,18 @@ class C {
|
||||
|
||||
void foo(int x) {
|
||||
|
||||
newMethod(x, 1, "A" + "B" + "C" + "D" + "E" + 1);
|
||||
newMethod(x, 1);
|
||||
|
||||
|
||||
newMethod(x, 2, "A" + "B" + "C" + "D" + "E" + 2);
|
||||
newMethod(x, 2);
|
||||
|
||||
if (x <= A + B + C + D + E + 2)
|
||||
bar("A" + "B" + "C" + "D" + "E" + 2);
|
||||
}
|
||||
|
||||
private void newMethod(int x, int i, String s) {
|
||||
private void newMethod(int x, int i) {
|
||||
if (x >= A + B + C + D + E + i)
|
||||
bar(s);
|
||||
bar("A" + "B" + "C" + "D" + "E" + i);
|
||||
}
|
||||
|
||||
void bar(String s) {}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user