Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
硅谷海盗
kotlin
提交
ff7576f8
K
kotlin
项目概览
硅谷海盗
/
kotlin
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kotlin
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ff7576f8
编写于
6月 09, 2020
作者:
N
Nikita Bobko
提交者:
Nikolay Krasko
6月 10, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
202: Fix compilation
上级
eb67c451
变更
19
隐藏空白更改
内联
并排
Showing
19 changed file
with
2193 addition
and
35 deletion
+2193
-35
idea/idea-gradle/src/org/jetbrains/kotlin/idea/actions/ShowKotlinGradleDslLogs.kt.202
...brains/kotlin/idea/actions/ShowKotlinGradleDslLogs.kt.202
+88
-0
idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/PluginTestCaseBase.java.202
...rg/jetbrains/kotlin/idea/test/PluginTestCaseBase.java.202
+137
-0
idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/compat.kt.202
...amework/test/org/jetbrains/kotlin/idea/test/compat.kt.202
+20
-0
idea/performanceTests/test/org/jetbrains/kotlin/idea/testFramework/gradleRoutines.kt.202
...jetbrains/kotlin/idea/testFramework/gradleRoutines.kt.202
+83
-0
idea/performanceTests/test/org/jetbrains/kotlin/idea/testFramework/projectRoutines.kt.202
...etbrains/kotlin/idea/testFramework/projectRoutines.kt.202
+120
-0
idea/scripting-support/test/org/jetbrains/kotlin/idea/scratch/ScratchLineMarkersTest.kt.202
...tbrains/kotlin/idea/scratch/ScratchLineMarkersTest.kt.202
+75
-0
idea/src/org/jetbrains/kotlin/idea/inspections/TrailingCommaInspection.kt.202
...ns/kotlin/idea/inspections/TrailingCommaInspection.kt.202
+192
-0
idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/KotlinMutableMethodDescriptor.kt.202
...ring/changeSignature/KotlinMutableMethodDescriptor.kt.202
+48
-0
idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinTargetElementEvaluator.kt.202
...search/ideaExtensions/KotlinTargetElementEvaluator.kt.202
+111
-0
idea/src/org/jetbrains/kotlin/idea/slicer/KotlinSliceProvider.kt.202
...g/jetbrains/kotlin/idea/slicer/KotlinSliceProvider.kt.202
+127
-0
idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractLineMarkersTest.kt.202
...ns/kotlin/idea/codeInsight/AbstractLineMarkersTest.kt.202
+185
-0
idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractLineMarkersTestInLibrarySources.kt.202
...odeInsight/AbstractLineMarkersTestInLibrarySources.kt.202
+91
-0
idea/tests/org/jetbrains/kotlin/idea/highlighter/AbstractUsageHighlightingTest.kt.202
...lin/idea/highlighter/AbstractUsageHighlightingTest.kt.202
+64
-0
idea/tests/org/jetbrains/kotlin/idea/inspections/InspectionDescriptionTest.kt.202
.../kotlin/idea/inspections/InspectionDescriptionTest.kt.202
+149
-0
idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionDescriptionTest.kt.202
...ns/kotlin/idea/intentions/IntentionDescriptionTest.kt.202
+65
-0
idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerTestUtil.kt.202
...ts/org/jetbrains/kotlin/idea/slicer/SlicerTestUtil.kt.202
+136
-0
idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiHighlightingTest.kt.202
...ns/kotlin/idea/stubs/AbstractMultiHighlightingTest.kt.202
+50
-0
jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt.202
.../org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt.202
+23
-35
plugins/uast-kotlin-idea/src/org/jetbrains/uast/kotlin/generate/KotlinUastCodeGenerationPlugin.kt.202
...ast/kotlin/generate/KotlinUastCodeGenerationPlugin.kt.202
+429
-0
未找到文件。
idea/idea-gradle/src/org/jetbrains/kotlin/idea/actions/ShowKotlinGradleDslLogs.kt.202
0 → 100644
浏览文件 @
ff7576f8
/*
*
Copyright
2010
-
2019
JetBrains
s
.
r
.
o
.
and
Kotlin
Programming
Language
contributors
.
*
Use
of
this
source
code
is
governed
by
the
Apache
2.0
license
that
can
be
found
in
the
license
/
LICENSE
.
txt
file
.
*/
package
org
.
jetbrains
.
kotlin
.
idea
.
actions
import
com
.
intellij
.
codeInsight
.
intention
.
IntentionAction
import
com
.
intellij
.
ide
.
actions
.
RevealFileAction
import
com
.
intellij
.
openapi
.
actionSystem
.
AnAction
import
com
.
intellij
.
openapi
.
actionSystem
.
AnActionEvent
import
com
.
intellij
.
openapi
.
editor
.
Editor
import
com
.
intellij
.
openapi
.
project
.
DumbAware
import
com
.
intellij
.
openapi
.
project
.
Project
import
com
.
intellij
.
openapi
.
ui
.
MessageType
import
com
.
intellij
.
openapi
.
ui
.
popup
.
JBPopupFactory
import
com
.
intellij
.
openapi
.
util
.
SystemInfo
import
com
.
intellij
.
openapi
.
wm
.
WindowManager
import
com
.
intellij
.
psi
.
PsiFile
import
com
.
intellij
.
ui
.
BrowserHyperlinkListener
import
org
.
jetbrains
.
kotlin
.
idea
.
KotlinIdeaGradleBundle
import
java
.
io
.
File
class
ShowKotlinGradleDslLogs
:
IntentionAction
,
AnAction
(),
DumbAware
{
override
fun
invoke
(
project
:
Project
,
editor
:
Editor
?,
file
:
PsiFile
?)
{
openLogsDirIfPresent
(
project
)
}
override
fun
actionPerformed
(
e
:
AnActionEvent
)
{
val
project
=
e
.
project
?:
return
openLogsDirIfPresent
(
project
)
}
override
fun
isAvailable
(
project
:
Project
,
editor
:
Editor
?,
file
:
PsiFile
?)
=
RevealFileAction
.
isSupported
()
override
fun
update
(
e
:
AnActionEvent
)
{
val
presentation
=
e
.
presentation
presentation
.
isEnabledAndVisible
=
e
.
project
!= null && RevealFileAction.isSupported()
presentation
.
text
=
NAME
}
private
fun
openLogsDirIfPresent
(
project
:
Project
)
{
val
logsDir
=
findLogsDir
()
if
(
logsDir
!= null) {
RevealFileAction
.
openDirectory
(
logsDir
)
}
else
{
val
parent
=
WindowManager
.
getInstance
().
getStatusBar
(
project
)?.
component
?:
WindowManager
.
getInstance
().
findVisibleFrame
()?.
rootPane
JBPopupFactory
.
getInstance
()
.
createHtmlTextBalloonBuilder
(
KotlinIdeaGradleBundle
.
message
(
"text.gradle.dsl.logs.cannot.be.found.automatically.see.how.to.find.logs"
,
gradleTroubleshootingLink
),
MessageType
.
ERROR
,
BrowserHyperlinkListener
.
INSTANCE
)
.
setFadeoutTime
(
5000
)
.
createBalloon
()
.
showInCenterOf
(
parent
)
}
}
/**
The
way
how
to
find
Gradle
logs
is
described
here
*
@
see
org
.
jetbrains
.
kotlin
.
idea
.
actions
.
ShowKotlinGradleDslLogs
.
gradleTroubleshootingLink
*/
private
fun
findLogsDir
():
File
?
{
val
userHome
=
System
.
getProperty
(
"user.home"
)
return
when
{
SystemInfo
.
isMac
->
File
(
"$userHome/Library/Logs/gradle-kotlin-dsl"
)
SystemInfo
.
isLinux
->
File
(
"$userHome/.gradle-kotlin-dsl/logs"
)
SystemInfo
.
isWindows
->
File
(
"$userHome/AppData/Local/gradle-kotlin-dsl/log"
)
else
->
null
}.
takeIf
{
it
?.
exists
()
==
true
}
}
override
fun
startInWriteAction
()
=
false
override
fun
getText
()
=
NAME
override
fun
getFamilyName
()
=
NAME
companion
object
{
private
const
val
gradleTroubleshootingLink
=
"https://docs.gradle.org/current/userguide/kotlin_dsl.html#troubleshooting"
val
NAME
=
KotlinIdeaGradleBundle
.
message
(
"action.text.show.kotlin.gradle.dsl.logs.in"
,
RevealFileAction
.
getFileManagerName
())
}
}
\ No newline at end of file
idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/PluginTestCaseBase.java.202
0 → 100644
浏览文件 @
ff7576f8
/*
*
Copyright
2010
-
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
.
*/
package
org
.
jetbrains
.
kotlin
.
idea
.
test
;
import
com
.
intellij
.
openapi
.
Disposable
;
import
com
.
intellij
.
openapi
.
application
.
ApplicationManager
;
import
com
.
intellij
.
openapi
.
projectRoots
.
JavaSdk
;
import
com
.
intellij
.
openapi
.
projectRoots
.
ProjectJdkTable
;
import
com
.
intellij
.
openapi
.
projectRoots
.
Sdk
;
import
com
.
intellij
.
openapi
.
projectRoots
.
impl
.
JavaSdkImpl
;
import
com
.
intellij
.
openapi
.
util
.
Disposer
;
import
com
.
intellij
.
openapi
.
util
.
text
.
StringUtil
;
import
com
.
intellij
.
openapi
.
vfs
.
newvfs
.
impl
.
VfsRootAccess
;
import
com
.
intellij
.
testFramework
.
IdeaTestUtil
;
import
kotlin
.
jvm
.
functions
.
Function0
;
import
org
.
jetbrains
.
annotations
.
NotNull
;
import
org
.
jetbrains
.
annotations
.
TestOnly
;
import
org
.
jetbrains
.
kotlin
.
idea
.
util
.
IjPlatformUtil
;
import
org
.
jetbrains
.
kotlin
.
test
.
KotlinTestUtils
;
import
org
.
jetbrains
.
kotlin
.
test
.
TestJdkKind
;
import
java
.
io
.
File
;
public
class
PluginTestCaseBase
{
public
static
final
String
TEST_DATA_DIR
=
"idea/testData"
;
public
static
final
String
TEST_DATA_PROJECT_RELATIVE
=
"/"
+
TEST_DATA_DIR
;
private
PluginTestCaseBase
()
{
}
@
NotNull
public
static
String
getTestDataPathBase
()
{
return
KotlinTestUtils
.
getHomeDirectory
()
+
TEST_DATA_PROJECT_RELATIVE
;
}
@
NotNull
@
TestOnly
private
static
Sdk
createMockJdk
(@
NotNull
String
name
,
String
path
)
{
return
IdeaTestUtil
.
createMockJdk
(
name
,
path
,
false
);
}
@
NotNull
private
static
Sdk
getSdk
(
String
sdkHome
,
String
name
)
{
ProjectJdkTable
table
=
IjPlatformUtil
.
getProjectJdkTableSafe
();
Sdk
existing
=
table
.
findJdk
(
name
);
if
(
existing
!= null) {
return
existing
;
}
return
JavaSdk
.
getInstance
().
createJdk
(
name
,
sdkHome
,
true
);
}
@
NotNull
public
static
Sdk
mockJdk
()
{
return
getSdk
(
"compiler/testData/mockJDK/jre"
,
"Mock JDK"
);
}
@
NotNull
public
static
Sdk
mockJdk6
()
{
return
getSdk
(
"compiler/testData/mockJDK/jre"
,
"1.6"
);
}
@
NotNull
public
static
Sdk
mockJdk8
()
{
//
Using
JDK
6
,
but
with
version
1.8
return
getSdk
(
"compiler/testData/mockJDK/jre"
,
"1.8"
);
}
@
TestOnly
@
NotNull
public
static
Sdk
mockJdk9
()
{
return
getSdk
(
"compiler/testData/mockJDK9/jre"
,
"9"
);
}
@
NotNull
public
static
Sdk
fullJdk
()
{
String
javaHome
=
System
.
getProperty
(
"java.home"
);
assert
new
File
(
javaHome
).
isDirectory
();
return
getSdk
(
javaHome
,
"Full JDK"
);
}
@
NotNull
public
static
Sdk
addJdk
(@
NotNull
Disposable
disposable
,
@
NotNull
Function0
<
Sdk
>
getJdk
)
{
Sdk
jdk
=
getJdk
.
invoke
();
Sdk
[]
allJdks
=
IjPlatformUtil
.
getProjectJdkTableSafe
().
getAllJdks
();
for
(
Sdk
existingJdk
:
allJdks
)
{
if
(
existingJdk
==
jdk
)
{
return
existingJdk
;
}
}
ApplicationManager
.
getApplication
().
runWriteAction
(()
->
IjPlatformUtil
.
getProjectJdkTableSafe
().
addJdk
(
jdk
,
disposable
));
return
jdk
;
}
@
NotNull
public
static
Sdk
jdk
(@
NotNull
TestJdkKind
kind
)
{
switch
(
kind
)
{
case
MOCK_JDK
:
return
mockJdk
();
case
FULL_JDK_9
:
String
jre9
=
KotlinTestUtils
.
getJdk9Home
().
getPath
();
VfsRootAccess
.
allowRootAccess
(
jre9
);
return
getSdk
(
jre9
,
"Full JDK 9"
);
case
FULL_JDK
:
return
fullJdk
();
default
:
throw
new
UnsupportedOperationException
(
kind
.
toString
());
}
}
public
static
boolean
isAllFilesPresentTest
(@
NotNull
String
testName
)
{
return
StringUtil
.
startsWithIgnoreCase
(
testName
,
"allFilesPresentIn"
);
}
@
TestOnly
public
static
void
clearSdkTable
(@
NotNull
Disposable
disposable
)
{
Disposer
.
register
(
disposable
,
()
->
ApplicationManager
.
getApplication
().
runWriteAction
(()
->
{
ProjectJdkTable
jdkTable
=
IjPlatformUtil
.
getProjectJdkTableSafe
();
for
(
Sdk
sdk
:
jdkTable
.
getAllJdks
())
{
jdkTable
.
removeJdk
(
sdk
);
}
}));
}
}
idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/compat.kt.202
0 → 100644
浏览文件 @
ff7576f8
/*
*
Copyright
2010
-
2020
JetBrains
s
.
r
.
o
.
and
Kotlin
Programming
Language
contributors
.
*
Use
of
this
source
code
is
governed
by
the
Apache
2.0
license
that
can
be
found
in
the
license
/
LICENSE
.
txt
file
.
*/
package
org
.
jetbrains
.
kotlin
.
idea
.
test
import
com
.
intellij
.
codeInsight
.
daemon
.
impl
.
EditorTracker
import
com
.
intellij
.
ide
.
startup
.
impl
.
StartupManagerImpl
import
com
.
intellij
.
openapi
.
project
.
Project
import
com
.
intellij
.
openapi
.
startup
.
StartupManager
//
FIX
ME
WHEN
BUNCH
192
REMOVED
fun
editorTrackerProjectOpened
(
project
:
Project
)
{
EditorTracker
.
getInstance
(
project
)
}
//
FIX
ME
WHEN
BUNCH
193
REMOVED
fun
runPostStartupActivitiesOnce
(
project
:
Project
)
{
}
idea/performanceTests/test/org/jetbrains/kotlin/idea/testFramework/gradleRoutines.kt.202
0 → 100644
浏览文件 @
ff7576f8
/*
*
Copyright
2010
-
2019
JetBrains
s
.
r
.
o
.
and
Kotlin
Programming
Language
contributors
.
*
Use
of
this
source
code
is
governed
by
the
Apache
2.0
license
that
can
be
found
in
the
license
/
LICENSE
.
txt
file
.
*/
package
org
.
jetbrains
.
kotlin
.
idea
.
testFramework
import
com
.
intellij
.
openapi
.
externalSystem
.
importing
.
ImportSpecBuilder
import
com
.
intellij
.
openapi
.
externalSystem
.
service
.
execution
.
ProgressExecutionMode
import
com
.
intellij
.
openapi
.
externalSystem
.
service
.
project
.
manage
.
ExternalProjectsManagerImpl
import
com
.
intellij
.
openapi
.
externalSystem
.
util
.
ExternalSystemApiUtil
import
com
.
intellij
.
openapi
.
externalSystem
.
util
.
ExternalSystemUtil
import
com
.
intellij
.
openapi
.
project
.
DumbService
import
com
.
intellij
.
openapi
.
project
.
Project
import
com
.
intellij
.
openapi
.
roots
.
ProjectRootManager
import
org
.
gradle
.
util
.
GradleVersion
import
org
.
jetbrains
.
plugins
.
gradle
.
service
.
project
.
open
.
setupGradleSettings
import
org
.
jetbrains
.
plugins
.
gradle
.
settings
.
GradleProjectSettings
import
org
.
jetbrains
.
plugins
.
gradle
.
settings
.
GradleSettings
import
org
.
jetbrains
.
plugins
.
gradle
.
util
.
GradleConstants
import
org
.
jetbrains
.
plugins
.
gradle
.
util
.
GradleLog
import
org
.
jetbrains
.
plugins
.
gradle
.
util
.
suggestGradleVersion
import
java
.
io
.
File
import
kotlin
.
test
.
assertNotNull
fun
refreshGradleProject
(
projectPath
:
String
,
project
:
Project
)
{
_importProject
(
File
(
projectPath
).
absolutePath
,
project
)
dispatchAllInvocationEvents
()
}
const
val
GRADLE_JDK_NAME
=
"Gradle JDK"
/**
*
inspired
by
org
.
jetbrains
.
plugins
.
gradle
.
service
.
project
.
open
.
importProject
(
projectDirectory
,
project
)
*/
private
fun
_importProject
(
projectPath
:
String
,
project
:
Project
)
{
GradleLog
.
LOG
.
info
(
"Import project at $projectPath"
)
val
gradleProjectSettings
=
GradleProjectSettings
()
val
gradleVersion
=
suggestGradleVersion
(
project
)
?:
GradleVersion
.
current
()
GradleSettings
.
getInstance
(
project
).
gradleVmOptions
=
"-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${System.getProperty("
user
.
dir
")}"
setupGradleSettings
(
project
,
gradleProjectSettings
,
projectPath
,
gradleVersion
)
gradleProjectSettings
.
gradleJvm
=
GRADLE_JDK_NAME
GradleSettings
.
getInstance
(
project
).
getLinkedProjectSettings
(
projectPath
)?.
let
{
linkedProjectSettings
->
linkedProjectSettings
.
gradleJvm
=
GRADLE_JDK_NAME
}
_attachGradleProjectAndRefresh
(
gradleProjectSettings
,
project
)
}
/**
*
inspired
by
org
.
jetbrains
.
plugins
.
gradle
.
service
.
project
.
open
.
attachGradleProjectAndRefresh
(
gradleProjectSettings
,
project
)
*
except
everything
is
MODAL_SYNC
*/
private
fun
_attachGradleProjectAndRefresh
(
gradleProjectSettings
:
GradleProjectSettings
,
project
:
Project
)
{
val
externalProjectPath
=
gradleProjectSettings
.
externalProjectPath
ExternalProjectsManagerImpl
.
getInstance
(
project
).
runWhenInitialized
{
DumbService
.
getInstance
(
project
).
runWhenSmart
{
ExternalSystemUtil
.
ensureToolWindowInitialized
(
project
,
GradleConstants
.
SYSTEM_ID
)
}
}
val
settings
=
ExternalSystemApiUtil
.
getSettings
(
project
,
GradleConstants
.
SYSTEM_ID
)
if
(
settings
.
getLinkedProjectSettings
(
externalProjectPath
)
==
null
)
{
settings
.
linkProject
(
gradleProjectSettings
)
}
StatefulTestGradleProjectRefreshCallback
(
externalProjectPath
,
project
).
use
{
callback
->
ExternalSystemUtil
.
refreshProject
(
externalProjectPath
,
ImportSpecBuilder
(
project
,
GradleConstants
.
SYSTEM_ID
)
.
use
(
ProgressExecutionMode
.
MODAL_SYNC
)
.
callback
(
callback
)
.
build
()
)
}
}
idea/performanceTests/test/org/jetbrains/kotlin/idea/testFramework/projectRoutines.kt.202
0 → 100644
浏览文件 @
ff7576f8
/*
*
Copyright
2010
-
2019
JetBrains
s
.
r
.
o
.
and
Kotlin
Programming
Language
contributors
.
*
Use
of
this
source
code
is
governed
by
the
Apache
2.0
license
that
can
be
found
in
the
license
/
LICENSE
.
txt
file
.
*/
package
org
.
jetbrains
.
kotlin
.
idea
.
testFramework
import
com
.
intellij
.
codeInsight
.
daemon
.
DaemonCodeAnalyzer
import
com
.
intellij
.
codeInsight
.
daemon
.
DaemonCodeAnalyzerSettings
import
com
.
intellij
.
codeInsight
.
daemon
.
impl
.
DaemonCodeAnalyzerImpl
import
com
.
intellij
.
ide
.
impl
.
OpenProjectTask
import
com
.
intellij
.
ide
.
startup
.
impl
.
StartupManagerImpl
import
com
.
intellij
.
lang
.
LanguageAnnotators
import
com
.
intellij
.
lang
.
LanguageExtensionPoint
import
com
.
intellij
.
lang
.
annotation
.
Annotator
import
com
.
intellij
.
openapi
.
Disposable
import
com
.
intellij
.
openapi
.
editor
.
Document
import
com
.
intellij
.
openapi
.
extensions
.
ExtensionPointName
import
com
.
intellij
.
openapi
.
fileEditor
.
FileDocumentManager
import
com
.
intellij
.
openapi
.
project
.
Project
import
com
.
intellij
.
openapi
.
project
.
ex
.
ProjectManagerEx
import
com
.
intellij
.
openapi
.
startup
.
StartupManager
import
com
.
intellij
.
platform
.
PlatformProjectOpenProcessor
import
com
.
intellij
.
psi
.
PsiDocumentManager
import
com
.
intellij
.
psi
.
impl
.
PsiDocumentManagerBase
import
com
.
intellij
.
testFramework
.
ExtensionTestUtil
import
com
.
intellij
.
testFramework
.
runInEdtAndWait
import
com
.
intellij
.
util
.
ui
.
UIUtil
import
org
.
jetbrains
.
kotlin
.
idea
.
parameterInfo
.
HintType
import
org
.
jetbrains
.
kotlin
.
idea
.
perf
.
util
.
logMessage
import
org
.
jetbrains
.
kotlin
.
idea
.
test
.
runPostStartupActivitiesOnce
import
java
.
nio
.
file
.
Paths
fun
commitAllDocuments
()
{
val
fileDocumentManager
=
FileDocumentManager
.
getInstance
()
runInEdtAndWait
{
fileDocumentManager
.
saveAllDocuments
()
}
ProjectManagerEx
.
getInstanceEx
().
openProjects
.
forEach
{
project
->
val
psiDocumentManagerBase
=
PsiDocumentManager
.
getInstance
(
project
)
as
PsiDocumentManagerBase
runInEdtAndWait
{
psiDocumentManagerBase
.
clearUncommittedDocuments
()
psiDocumentManagerBase
.
commitAllDocuments
()
}
}
}
fun
commitDocument
(
project
:
Project
,
document
:
Document
)
{
val
psiDocumentManagerBase
=
PsiDocumentManager
.
getInstance
(
project
)
as
PsiDocumentManagerBase
runInEdtAndWait
{
psiDocumentManagerBase
.
commitDocument
(
document
)
}
}
fun
saveDocument
(
document
:
Document
)
{
val
fileDocumentManager
=
FileDocumentManager
.
getInstance
()
runInEdtAndWait
{
fileDocumentManager
.
saveDocument
(
document
)
}
}
fun
enableHints
(
enable
:
Boolean
)
=
HintType
.
values
().
forEach
{
it
.
option
.
set
(
enable
)
}
fun
dispatchAllInvocationEvents
()
{
runInEdtAndWait
{
UIUtil
.
dispatchAllInvocationEvents
()
}
}
fun
loadProjectWithName
(
path
:
String
,
name
:
String
):
Project
?
=
PlatformProjectOpenProcessor
.
openExistingProject
(
Paths
.
get
(
path
),
Paths
.
get
(
path
),
OpenProjectTask
(
projectName
=
name
))
fun
TestApplicationManager
.
closeProject
(
project
:
Project
)
{
val
name
=
project
.
name
val
startupManagerImpl
=
StartupManager
.
getInstance
(
project
)
as
StartupManagerImpl
val
daemonCodeAnalyzerSettings
=
DaemonCodeAnalyzerSettings
.
getInstance
()
val
daemonCodeAnalyzerImpl
=
DaemonCodeAnalyzer
.
getInstance
(
project
)
as
DaemonCodeAnalyzerImpl
setDataProvider
(
null
)
daemonCodeAnalyzerSettings
.
isImportHintEnabled
=
true
//
return
default
value
to
avoid
unnecessary
save
startupManagerImpl
.
checkCleared
()
daemonCodeAnalyzerImpl
.
cleanupAfterTest
()
logMessage
{
"project '$name' is about to be closed"
}
dispatchAllInvocationEvents
()
val
projectManagerEx
=
ProjectManagerEx
.
getInstanceEx
()
projectManagerEx
.
forceCloseProjectEx
(
project
,
true
)
logMessage
{
"project '$name' successfully closed"
}
}
fun
runStartupActivities
(
project
:
Project
)
{
//
obsolete
}
fun
waitForAllEditorsFinallyLoaded
(
project
:
Project
)
{
//
routing
is
obsolete
in
192
}
fun
replaceWithCustomHighlighter
(
parentDisposable
:
Disposable
,
fromImplementationClass
:
String
,
toImplementationClass
:
String
)
{
val
pointName
=
ExtensionPointName
.
create
<
LanguageExtensionPoint
<
Annotator
>>(
LanguageAnnotators
.
EP_NAME
.
name
)
val
extensionPoint
=
pointName
.
getPoint
(
null
)
val
point
=
LanguageExtensionPoint
<
Annotator
>()
point
.
language
=
"kotlin"
point
.
implementationClass
=
toImplementationClass
val
extensions
=
extensionPoint
.
extensions
val
filteredExtensions
=
extensions
.
filter
{
it
.
language
!= "kotlin" || it.implementationClass != fromImplementationClass }
.
toList
()
//
custom
highlighter
is
already
registered
if
filteredExtensions
has
the
same
size
as
extensions
if
(
filteredExtensions
.
size
<
extensions
.
size
)
{
ExtensionTestUtil
.
maskExtensions
(
pointName
,
filteredExtensions
+
listOf
(
point
),
parentDisposable
)
}
}
\ No newline at end of file
idea/scripting-support/test/org/jetbrains/kotlin/idea/scratch/ScratchLineMarkersTest.kt.202
0 → 100644
浏览文件 @
ff7576f8
/*
*
Copyright
2010
-
2019
JetBrains
s
.
r
.
o
.
and
Kotlin
Programming
Language
contributors
.
*
Use
of
this
source
code
is
governed
by
the
Apache
2.0
license
that
can
be
found
in
the
license
/
LICENSE
.
txt
file
.
*/
package
org
.
jetbrains
.
kotlin
.
idea
.
scratch
import
com
.
intellij
.
codeInsight
.
daemon
.
LineMarkerInfo
import
com
.
intellij
.
ide
.
scratch
.
ScratchFileService
import
com
.
intellij
.
ide
.
scratch
.
ScratchRootType
import
com
.
intellij
.
openapi
.
editor
.
Document
import
com
.
intellij
.
openapi
.
fileEditor
.
FileEditorManager
import
com
.
intellij
.
openapi
.
util
.
io
.
FileUtil
import
com
.
intellij
.
psi
.
PsiDocumentManager
import
com
.
intellij
.
testFramework
.
ExpectedHighlightingData
import
com
.
intellij
.
testFramework
.
FileEditorManagerTestCase
import
org
.
jetbrains
.
kotlin
.
idea
.
KotlinLanguage
import
org
.
jetbrains
.
kotlin
.
idea
.
codeInsight
.
AbstractLineMarkersTest
import
org
.
jetbrains
.
kotlin
.
idea
.
core
.
script
.
ScriptConfigurationManager
import
org
.
jetbrains
.
kotlin
.
idea
.
scratch
.
AbstractScratchRunActionTest
.
Companion
.
configureOptions
import
org
.
jetbrains
.
kotlin
.
idea
.
util
.
application
.
runWriteAction
import
org
.
jetbrains
.
kotlin
.
psi
.
KtFile
import
java
.
io
.
File
abstract
class
AbstractScratchLineMarkersTest
:
FileEditorManagerTestCase
()
{
fun
doScratchTest
(
path
:
String
)
{
val
fileText
=
FileUtil
.
loadFile
(
File
(
path
))
val
scratchVirtualFile
=
ScratchRootType
.
getInstance
().
createScratchFile
(
project
,
"scratch.kts"
,
KotlinLanguage
.
INSTANCE
,
fileText
,
ScratchFileService
.
Option
.
create_if_missing
)
?:
error
(
"Couldn't create scratch file"
)
myFixture
.
openFileInEditor
(
scratchVirtualFile
)
ScriptConfigurationManager
.
updateScriptDependenciesSynchronously
(
myFixture
.
file
)
val
scratchFileEditor
=
getScratchEditorForSelectedFile
(
FileEditorManager
.
getInstance
(
project
),
myFixture
.
file
.
virtualFile
)
?:
error
(
"Couldn't find scratch panel"
)
configureOptions
(
scratchFileEditor
,
fileText
,
null
)
val
project
=
myFixture
.
project
val
document
=
myFixture
.
editor
.
document
val
data
=
ExpectedHighlightingData
(
document
,
false
,
false
,
false
)
data
.
init
()
PsiDocumentManager
.
getInstance
(
project
).
commitAllDocuments
()
val
markers
=
doAndCheckHighlighting
(
document
,
data
,
File
(
path
))
AbstractLineMarkersTest
.
assertNavigationElements
(
myFixture
.
project
,
myFixture
.
file
as
KtFile
,
markers
)
}
override
fun
tearDown
()
{
super
.
tearDown
()
ScratchFileService
.
getInstance
().
scratchesMapping
.
mappings
.
forEach
{
file
,
_
->
runWriteAction
{
file
.
delete
(
this
)
}
}
}
private
fun
doAndCheckHighlighting
(
documentToAnalyze
:
Document
,
expectedHighlighting
:
ExpectedHighlightingData
,
expectedFile
:
File
):
List
<
LineMarkerInfo
<*>>
{
myFixture
.
doHighlighting
()
return
AbstractLineMarkersTest
.
checkHighlighting
(
myFixture
.
file
,
documentToAnalyze
,
expectedHighlighting
,
expectedFile
)
}
}
\ No newline at end of file
idea/src/org/jetbrains/kotlin/idea/inspections/TrailingCommaInspection.kt.202
0 → 100644
浏览文件 @
ff7576f8
/*
*
Copyright
2010
-
2020
JetBrains
s
.
r
.
o
.
and
Kotlin
Programming
Language
contributors
.
*
Use
of
this
source
code
is
governed
by
the
Apache
2.0
license
that
can
be
found
in
the
license
/
LICENSE
.
txt
file
.
*/
package
org
.
jetbrains
.
kotlin
.
idea
.
inspections
import
com
.
intellij
.
application
.
options
.
CodeStyle
import
com
.
intellij
.
codeInspection
.
LocalQuickFix
import
com
.
intellij
.
codeInspection
.
ProblemDescriptor
import
com
.
intellij
.
codeInspection
.
ProblemHighlightType
import
com
.
intellij
.
codeInspection
.
ProblemsHolder
import
com
.
intellij
.
codeInspection
.
ui
.
MultipleCheckboxOptionsPanel
import
com
.
intellij
.
openapi
.
application
.
ApplicationManager
import
com
.
intellij
.
openapi
.
project
.
Project
import
com
.
intellij
.
openapi
.
util
.
TextRange
import
com
.
intellij
.
psi
.
PsiElement
import
com
.
intellij
.
psi
.
PsiElementVisitor
import
com
.
intellij
.
psi
.
codeStyle
.
CodeStyleManager
import
org
.
jetbrains
.
kotlin
.
idea
.
KotlinBundle
import
org
.
jetbrains
.
kotlin
.
idea
.
formatter
.
TrailingCommaVisitor
import
org
.
jetbrains
.
kotlin
.
idea
.
formatter
.
kotlinCustomSettings
import
org
.
jetbrains
.
kotlin
.
idea
.
formatter
.
trailingComma
.*
import
org
.
jetbrains
.
kotlin
.
idea
.
formatter
.
trailingCommaAllowedInModule
import
org
.
jetbrains
.
kotlin
.
idea
.
util
.
isComma
import
org
.
jetbrains
.
kotlin
.
idea
.
util
.
isLineBreak
import
org
.
jetbrains
.
kotlin
.
idea
.
util
.
leafIgnoringWhitespaceAndComments
import
org
.
jetbrains
.
kotlin
.
psi
.
KtElement
import
org
.
jetbrains
.
kotlin
.
psi
.
psiUtil
.*
import
javax
.
swing
.
JComponent
import
kotlin
.
properties
.
Delegates
class
TrailingCommaInspection
(
@
JvmField
var
addCommaWarning
:
Boolean
=
false
)
:
AbstractKotlinInspection
()
{
override
fun
buildVisitor
(
holder
:
ProblemsHolder
,
isOnTheFly
:
Boolean
):
PsiElementVisitor
=
object
:
TrailingCommaVisitor
()
{
override
val
recursively
:
Boolean
=
false
private
var
useTrailingComma
by
Delegates
.
notNull
<
Boolean
>()
override
fun
process
(
trailingCommaContext
:
TrailingCommaContext
)
{
val
element
=
trailingCommaContext
.
ktElement
val
kotlinCustomSettings
=
CodeStyle
.
getSettings
(
element
.
project
).
kotlinCustomSettings
useTrailingComma
=
kotlinCustomSettings
.
addTrailingCommaIsAllowedFor
(
element
)
when
(
trailingCommaContext
.
state
)
{
TrailingCommaState
.
MISSING
,
TrailingCommaState
.
EXISTS
->
{
checkCommaPosition
(
element
)
checkLineBreaks
(
element
)
}
else
->
Unit
}
checkTrailingComma
(
trailingCommaContext
)
}
private
fun
checkLineBreaks
(
commaOwner
:
KtElement
)
{
val
first
=
TrailingCommaHelper
.
elementBeforeFirstElement
(
commaOwner
)
if
(
first
?.
nextLeaf
(
true
)?.
isLineBreak
()
==
false
)
{
first
.
nextSibling
?.
let
{
registerProblemForLineBreak
(
commaOwner
,
it
,
ProblemHighlightType
.
INFORMATION
)
}
}
val
last
=
TrailingCommaHelper
.
elementAfterLastElement
(
commaOwner
)
if
(
last
?.
prevLeaf
(
true
)?.
isLineBreak
()
==
false
)
{
registerProblemForLineBreak
(
commaOwner
,
last
,
if
(
addCommaWarning
)
ProblemHighlightType
.
GENERIC_ERROR_OR_WARNING
else
ProblemHighlightType
.
INFORMATION
,
)
}
}
private
fun
checkCommaPosition
(
commaOwner
:
KtElement
)
{
for
(
invalidComma
in
TrailingCommaHelper
.
findInvalidCommas
(
commaOwner
))
{
reportProblem
(
invalidComma
,
KotlinBundle
.
message
(
"inspection.trailing.comma.comma.loses.the.advantages.in.this.position"
),
KotlinBundle
.
message
(
"inspection.trailing.comma.fix.comma.position"
)
)
}
}
private
fun
checkTrailingComma
(
trailingCommaContext
:
TrailingCommaContext
)
{
val
commaOwner
=
trailingCommaContext
.
ktElement
val
trailingCommaOrLastElement
=
TrailingCommaHelper
.
trailingCommaOrLastElement
(
commaOwner
)
?:
return
when
(
trailingCommaContext
.
state
)
{
TrailingCommaState
.
MISSING
->
{
if
(
!trailingCommaAllowedInModule(commaOwner)) return
reportProblem
(
trailingCommaOrLastElement
,
KotlinBundle
.
message
(
"inspection.trailing.comma.missing.trailing.comma"
),
KotlinBundle
.
message
(
"inspection.trailing.comma.add.trailing.comma"
),
if
(
addCommaWarning
)
ProblemHighlightType
.
GENERIC_ERROR_OR_WARNING
else
ProblemHighlightType
.
INFORMATION
,
)
}
TrailingCommaState
.
REDUNDANT
->
{
reportProblem
(
trailingCommaOrLastElement
,
KotlinBundle
.
message
(
"inspection.trailing.comma.useless.trailing.comma"
),
KotlinBundle
.
message
(
"inspection.trailing.comma.remove.trailing.comma"
),
ProblemHighlightType
.
LIKE_UNUSED_SYMBOL
,
checkTrailingCommaSettings
=
false
,
)
}
else
->
Unit
}
}
private
fun
reportProblem
(
commaOrElement
:
PsiElement
,
message
:
String
,
fixMessage
:
String
,
highlightType
:
ProblemHighlightType
=
ProblemHighlightType
.
GENERIC_ERROR_OR_WARNING
,
checkTrailingCommaSettings
:
Boolean
=
true
,
)
{
val
commaOwner
=
commaOrElement
.
parent
as
KtElement
//
case
for
KtFunctionLiteral
,
where
PsiWhiteSpace
after
KtTypeParameterList
isn
't included in this list
val problemOwner = commaOwner.parent
holder.registerProblem(
problemOwner,
message,
highlightType.applyCondition(!checkTrailingCommaSettings || useTrailingComma),
commaOrElement.textRangeOfCommaOrSymbolAfter.shiftLeft(problemOwner.startOffset),
createQuickFix(fixMessage, commaOwner),
)
}
private fun registerProblemForLineBreak(
commaOwner: KtElement,
elementForTextRange: PsiElement,
highlightType: ProblemHighlightType,
) {
val problemElement = commaOwner.parent
holder.registerProblem(
problemElement,
KotlinBundle.message("inspection.trailing.comma.missing.line.break"),
highlightType.applyCondition(useTrailingComma),
TextRange.from(elementForTextRange.startOffset, 1).shiftLeft(problemElement.startOffset),
createQuickFix(KotlinBundle.message("inspection.trailing.comma.add.line.break"), commaOwner),
)
}
private fun ProblemHighlightType.applyCondition(condition: Boolean): ProblemHighlightType = when {
ApplicationManager.getApplication().isUnitTestMode -> ProblemHighlightType.GENERIC_ERROR_OR_WARNING
condition -> this
else -> ProblemHighlightType.INFORMATION
}
private fun createQuickFix(
fixMessage: String,
commaOwner: KtElement,
): LocalQuickFix = object : LocalQuickFix {
val commaOwnerPointer = commaOwner.createSmartPointer()
override fun getFamilyName(): String = fixMessage
override fun applyFix(project: Project, problemDescriptor: ProblemDescriptor) {
val element = commaOwnerPointer.element ?: return
val range = createFormatterTextRange(element)
val settings = CodeStyle.getSettings(project).clone()
settings.kotlinCustomSettings.ALLOW_TRAILING_COMMA = true
settings.kotlinCustomSettings.ALLOW_TRAILING_COMMA_ON_CALL_SITE = true
CodeStyle.doWithTemporarySettings(project, settings, Runnable {
CodeStyleManager.getInstance(project).reformatRange(element, range.startOffset, range.endOffset)
})
}
}
private fun createFormatterTextRange(commaOwner: KtElement): TextRange {
val startElement = TrailingCommaHelper.elementBeforeFirstElement(commaOwner) ?: commaOwner
val endElement = TrailingCommaHelper.elementAfterLastElement(commaOwner) ?: commaOwner
return TextRange.create(startElement.startOffset, endElement.endOffset)
}
private val PsiElement.textRangeOfCommaOrSymbolAfter: TextRange
get() {
val textRange = textRange
if (isComma) return textRange
return nextLeaf()?.leafIgnoringWhitespaceAndComments(false)?.endOffset?.takeIf { it > 0 }?.let {
TextRange.create(it - 1, it).intersection(textRange)
} ?: TextRange.create(textRange.endOffset - 1, textRange.endOffset)
}
}
override fun createOptionsPanel(): JComponent? {
val panel = MultipleCheckboxOptionsPanel(this)
panel.addCheckbox(KotlinBundle.message("inspection.trailing.comma.report.also.a.missing.comma"), "addCommaWarning")
return panel
}
}
\ No newline at end of file
idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/KotlinMutableMethodDescriptor.kt.202
0 → 100644
浏览文件 @
ff7576f8
/*
*
Copyright
2010
-
2019
JetBrains
s
.
r
.
o
.
and
Kotlin
Programming
Language
contributors
.
*
Use
of
this
source
code
is
governed
by
the
Apache
2.0
license
that
can
be
found
in
the
license
/
LICENSE
.
txt
file
.
*/
package
org
.
jetbrains
.
kotlin
.
idea
.
refactoring
.
changeSignature
import
org
.
jetbrains
.
kotlin
.
descriptors
.
Visibility
class
KotlinMutableMethodDescriptor
(
override
val
original
:
KotlinMethodDescriptor
)
:
KotlinMethodDescriptor
by
original
{
private
val
parameters
:
MutableList
<
KotlinParameterInfo
>
=
original
.
parameters
override
var
receiver
:
KotlinParameterInfo
?
=
original
.
receiver
set
(
value
:
KotlinParameterInfo
?)
{
if
(
value
!= null && value !in parameters) {
parameters
.
add
(
value
)
}
field
=
value
}
fun
addParameter
(
parameter
:
KotlinParameterInfo
)
{
parameters
.
add
(
parameter
)
}
fun
addParameter
(
index
:
Int
,
parameter
:
KotlinParameterInfo
)
{
parameters
.
add
(
index
,
parameter
)
}
fun
removeParameter
(
index
:
Int
)
{
val
paramInfo
=
parameters
.
removeAt
(
index
)
if
(
paramInfo
==
receiver
)
{
receiver
=
null
}
}
fun
renameParameter
(
index
:
Int
,
newName
:
String
)
{
parameters
[
index
].
name
=
newName
}
fun
clearNonReceiverParameters
()
{
parameters
.
clear
()
receiver
?.
let
{
parameters
.
add
(
it
)
}
}
override
fun
getVisibility
():
Visibility
{
return
original
.
visibility
}
}
\ No newline at end of file
idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinTargetElementEvaluator.kt.202
0 → 100644
浏览文件 @
ff7576f8
/*
*
Copyright
2010
-
2019
JetBrains
s
.
r
.
o
.
and
Kotlin
Programming
Language
contributors
.
*
Use
of
this
source
code
is
governed
by
the
Apache
2.0
license
that
can
be
found
in
the
license
/
LICENSE
.
txt
file
.
*/
package
org
.
jetbrains
.
kotlin
.
idea
.
search
.
ideaExtensions
import
com
.
intellij
.
codeInsight
.
JavaTargetElementEvaluator
import
com
.
intellij
.
codeInsight
.
TargetElementEvaluatorEx
import
com
.
intellij
.
codeInsight
.
TargetElementUtil
import
com
.
intellij
.
codeInsight
.
TargetElementUtilExtender
import
com
.
intellij
.
psi
.
PsiElement
import
com
.
intellij
.
psi
.
PsiFile
import
com
.
intellij
.
psi
.
PsiReference
import
com
.
intellij
.
util
.
BitUtil
import
org
.
jetbrains
.
kotlin
.
descriptors
.
CallableDescriptor
import
org
.
jetbrains
.
kotlin
.
descriptors
.
DeclarationDescriptorWithSource
import
org
.
jetbrains
.
kotlin
.
idea
.
intentions
.
isAutoCreatedItUsage
import
org
.
jetbrains
.
kotlin
.
idea
.
references
.
KtDestructuringDeclarationReference
import
org
.
jetbrains
.
kotlin
.
idea
.
references
.
KtSimpleNameReference
import
org
.
jetbrains
.
kotlin
.
idea
.
references
.
mainReference
import
org
.
jetbrains
.
kotlin
.
idea
.
references
.
resolveMainReferenceToDescriptors
import
org
.
jetbrains
.
kotlin
.
lexer
.
KtTokens
import
org
.
jetbrains
.
kotlin
.
psi
.*
import
org
.
jetbrains
.
kotlin
.
psi
.
psiUtil
.*
import
org
.
jetbrains
.
kotlin
.
resolve
.
descriptorUtil
.
isExtension
import
org
.
jetbrains
.
kotlin
.
resolve
.
source
.
getPsi
class
KotlinTargetElementEvaluator
:
TargetElementEvaluatorEx
,
TargetElementUtilExtender
{
companion
object
{
const
val
DO_NOT_UNWRAP_LABELED_EXPRESSION
=
0x100
const
val
BYPASS_IMPORT_ALIAS
=
0x200
//
Place
caret
after
the
open
curly
brace
in
lambda
for
generated
'it'
fun
findLambdaOpenLBraceForGeneratedIt
(
ref
:
PsiReference
):
PsiElement
?
{
val
element
:
PsiElement
=
ref
.
element
if
(
element
.
text
!= "it") return null
if
(
element
!is KtNameReferenceExpression || !isAutoCreatedItUsage(element)) return null
val
itDescriptor
=
element
.
resolveMainReferenceToDescriptors
().
singleOrNull
()
?:
return
null
val
descriptorWithSource
=
itDescriptor
.
containingDeclaration
as
?
DeclarationDescriptorWithSource
?:
return
null
val
lambdaExpression
=
descriptorWithSource
.
source
.
getPsi
()?.
parent
as
?
KtLambdaExpression
?:
return
null
return
lambdaExpression
.
leftCurlyBrace
.
treeNext
?.
psi
}
//
Navigate
to
receiver
element
for
this
in
extension
declaration
fun
findReceiverForThisInExtensionFunction
(
ref
:
PsiReference
):
PsiElement
?
{
val
element
:
PsiElement
=
ref
.
element
if
(
element
.
text
!= "this") return null
if
(
element
!is KtNameReferenceExpression) return null
val
callableDescriptor
=
element
.
resolveMainReferenceToDescriptors
().
singleOrNull
()
as
?
CallableDescriptor
?:
return
null
if
(
!callableDescriptor.isExtension) return null
val
callableDeclaration
=
callableDescriptor
.
source
.
getPsi
()
as
?
KtCallableDeclaration
?:
return
null
return
callableDeclaration
.
receiverTypeReference
}
}
override
fun
getAdditionalDefinitionSearchFlags
()
=
0
override
fun
getAdditionalReferenceSearchFlags
()
=
DO_NOT_UNWRAP_LABELED_EXPRESSION
or
BYPASS_IMPORT_ALIAS
override
fun
getAllAdditionalFlags
()
=
additionalDefinitionSearchFlags
+
additionalReferenceSearchFlags
override
fun
includeSelfInGotoImplementation
(
element
:
PsiElement
):
Boolean
=
!(element is KtClass && element.isAbstract())
override
fun
getElementByReference
(
ref
:
PsiReference
,
flags
:
Int
):
PsiElement
?
{
if
(
ref
is
KtSimpleNameReference
&&
ref
.
expression
is
KtLabelReferenceExpression
)
{
val
refTarget
=
ref
.
resolve
()
as
?
KtExpression
?:
return
null
if
(
!BitUtil.isSet(flags, DO_NOT_UNWRAP_LABELED_EXPRESSION)) {
return
refTarget
.
getLabeledParent
(
ref
.
expression
.
getReferencedName
())
?:
refTarget
}
return
refTarget
}
if
(
!BitUtil.isSet(flags, BYPASS_IMPORT_ALIAS)) {
(
ref
.
element
as
?
KtSimpleNameExpression
)?.
mainReference
?.
getImportAlias
()?.
let
{
return
it
}
}
//
prefer
destructing
declaration
entry
to
its
target
if
element
name
is
accepted
if
(
ref
is
KtDestructuringDeclarationReference
&&
BitUtil
.
isSet
(
flags
,
TargetElementUtil
.
ELEMENT_NAME_ACCEPTED
))
{
return
ref
.
element
}
val
refExpression
=
ref
.
element
as
?
KtSimpleNameExpression
val
calleeExpression
=
refExpression
?.
getParentOfTypeAndBranch
<
KtCallElement
>
{
calleeExpression
}
if
(
calleeExpression
!= null) {
(
ref
.
resolve
()
as
?
KtConstructor
<*>)?.
let
{
return
if
(
flags
and
JavaTargetElementEvaluator
().
additionalReferenceSearchFlags
!= 0) it else it.containingClassOrObject
}
}
if
(
BitUtil
.
isSet
(
flags
,
TargetElementUtil
.
REFERENCED_ELEMENT_ACCEPTED
))
{
return
findLambdaOpenLBraceForGeneratedIt
(
ref
)
?:
findReceiverForThisInExtensionFunction
(
ref
)
}
return
null
}
override
fun
isIdentifierPart
(
file
:
PsiFile
,
text
:
CharSequence
,
offset
:
Int
):
Boolean
{
val
elementAtCaret
=
file
.
findElementAt
(
offset
)
if
(
elementAtCaret
?.
node
?.
elementType
==
KtTokens
.
IDENTIFIER
)
return
true
//
'('
is
considered
identifier
part
if
it
belongs
to
primary
constructor
without
'constructor'
keyword
return
elementAtCaret
?.
getNonStrictParentOfType
<
KtPrimaryConstructor
>()?.
textOffset
==
offset
}
}
idea/src/org/jetbrains/kotlin/idea/slicer/KotlinSliceProvider.kt.202
0 → 100644
浏览文件 @
ff7576f8
/*
*
Copyright
2010
-
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
org
.
jetbrains
.
kotlin
.
idea
.
slicer
import
com
.
intellij
.
codeInsight
.
Nullability
import
com
.
intellij
.
ide
.
util
.
treeView
.
AbstractTreeStructure
import
com
.
intellij
.
openapi
.
actionSystem
.
DefaultActionGroup
import
com
.
intellij
.
psi
.
PsiElement
import
com
.
intellij
.
psi
.
util
.
parentOfType
import
com
.
intellij
.
slicer
.*
import
org
.
jetbrains
.
kotlin
.
builtins
.
KotlinBuiltIns
import
org
.
jetbrains
.
kotlin
.
descriptors
.
CallableDescriptor
import
org
.
jetbrains
.
kotlin
.
idea
.
caches
.
resolve
.
analyze
import
org
.
jetbrains
.
kotlin
.
idea
.
caches
.
resolve
.
resolveToDescriptorIfAny
import
org
.
jetbrains
.
kotlin
.
idea
.
references
.
KtReference
import
org
.
jetbrains
.
kotlin
.
idea
.
references
.
mainReference
import
org
.
jetbrains
.
kotlin
.
psi
.*
import
org
.
jetbrains
.
kotlin
.
psi
.
psiUtil
.
isPlainWithEscapes
import
org
.
jetbrains
.
kotlin
.
psi
.
psiUtil
.
parentsWithSelf
import
org
.
jetbrains
.
kotlin
.
psi2ir
.
deparenthesize
import
org
.
jetbrains
.
kotlin
.
resolve
.
lazy
.
BodyResolveMode
import
org
.
jetbrains
.
kotlin
.
types
.
TypeUtils
import
org
.
jetbrains
.
kotlin
.
types
.
isError
import
org
.
jetbrains
.
kotlin
.
types
.
isNullabilityFlexible
class
KotlinSliceProvider
:
SliceLanguageSupportProvider
,
SliceUsageTransformer
{
companion
object
{
val
LEAF_ELEMENT_EQUALITY
=
object
:
SliceLeafEquality
()
{
override
fun
substituteElement
(
element
:
PsiElement
)
=
(
element
as
?
KtReference
)?.
resolve
()
?:
element
}
}
class
KotlinGroupByNullnessAction
(
treeBuilder
:
SliceTreeBuilder
)
:
GroupByNullnessActionBase
(
treeBuilder
)
{
override
fun
isAvailable
()
=
true
}
val
leafAnalyzer
by
lazy
{
SliceLeafAnalyzer
(
LEAF_ELEMENT_EQUALITY
,
this
)
}
val
nullnessAnalyzer
:
HackedSliceNullnessAnalyzerBase
by
lazy
{
object
:
HackedSliceNullnessAnalyzerBase
(
LEAF_ELEMENT_EQUALITY
,
this
)
{
override
fun
checkNullability
(
element
:
PsiElement
?):
Nullability
{
val
types
=
when
(
element
)
{
is
KtCallableDeclaration
->
listOfNotNull
((
element
.
resolveToDescriptorIfAny
()
as
?
CallableDescriptor
)?.
returnType
)
is
KtDeclaration
->
emptyList
()
is
KtExpression
->
listOfNotNull
(
element
.
analyze
(
BodyResolveMode
.
PARTIAL
).
getType
(
element
))
else
->
emptyList
()
}
return
when
{
types
.
isEmpty
()
->
return
Nullability
.
UNKNOWN
types
.
all
{
KotlinBuiltIns
.
isNullableNothing
(
it
)
}
->
Nullability
.
NULLABLE
types
.
any
{
it
.
isError
||
TypeUtils
.
isNullableType
(
it
)
||
it
.
isNullabilityFlexible
()
}
->
Nullability
.
UNKNOWN
else
->
Nullability
.
NOT_NULL
}
}
}
}
override
fun
createRootUsage
(
element
:
PsiElement
,
params
:
SliceAnalysisParams
)
=
KotlinSliceUsage
(
element
,
params
)
override
fun
transform
(
usage
:
SliceUsage
):
Collection
<
SliceUsage
>?
{
if
(
usage
is
KotlinSliceUsage
)
return
null
return
listOf
(
KotlinSliceUsage
(
usage
.
element
?:
return
null
,
usage
.
parent
,
KotlinSliceAnalysisMode
.
Default
,
false
))
}
override
fun
getExpressionAtCaret
(
atCaret
:
PsiElement
,
dataFlowToThis
:
Boolean
):
KtElement
?
{
val
element
=
atCaret
.
parentsWithSelf
.
filterIsInstance
<
KtElement
>()
.
firstOrNull
(::
isSliceElement
)
?.
deparenthesize
()
?:
return
null
if
(
dataFlowToThis
)
{
if
(
element
is
KtConstantExpression
)
return
null
if
(
element
is
KtStringTemplateExpression
&&
element
.
isPlainWithEscapes
())
return
null
if
(
element
is
KtClassLiteralExpression
)
return
null
if
(
element
is
KtCallableReferenceExpression
)
return
null
}
return
element
}
private
fun
isSliceElement
(
element
:
KtElement
):
Boolean
{
return
when
{
element
is
KtProperty
->
true
element
is
KtParameter
->
true
element
is
KtDeclarationWithBody
->
true
element
is
KtClass
&&
!element.hasExplicitPrimaryConstructor() -> true
element
is
KtExpression
&&
element
!is KtDeclaration && element.parentOfType<KtTypeReference>() == null -> true
element
is
KtTypeReference
&&
element
==
(
element
.
parent
as
?
KtCallableDeclaration
)?.
receiverTypeReference
->
true
else
->
false
}
}
override
fun
getElementForDescription
(
element
:
PsiElement
):
PsiElement
{
return
(
element
as
?
KtSimpleNameExpression
)?.
mainReference
?.
resolve
()
?:
element
}
override
fun
getRenderer
()
=
KotlinSliceUsageCellRenderer
override
fun
startAnalyzeLeafValues
(
structure
:
AbstractTreeStructure
,
finalRunnable
:
Runnable
)
{
leafAnalyzer
.
startAnalyzeValues
(
structure
,
finalRunnable
)
}
override
fun
startAnalyzeNullness
(
structure
:
AbstractTreeStructure
,
finalRunnable
:
Runnable
)
{
nullnessAnalyzer
.
startAnalyzeNullness
(
structure
,
finalRunnable
)
}
override
fun
registerExtraPanelActions
(
group
:
DefaultActionGroup
,
builder
:
SliceTreeBuilder
)
{
if
(
builder
.
dataFlowToThis
)
{
group
.
add
(
GroupByLeavesAction
(
builder
))
group
.
add
(
KotlinGroupByNullnessAction
(
builder
))
}
}
}
\ No newline at end of file
idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractLineMarkersTest.kt.202
0 → 100644
浏览文件 @
ff7576f8
/*
*
Copyright
2010
-
2019
JetBrains
s
.
r
.
o
.
and
Kotlin
Programming
Language
contributors
.
*
Use
of
this
source
code
is
governed
by
the
Apache
2.0
license
that
can
be
found
in
the
license
/
LICENSE
.
txt
file
.
*/
package
org
.
jetbrains
.
kotlin
.
idea
.
codeInsight
import
com
.
intellij
.
codeInsight
.
daemon
.
DaemonCodeAnalyzerSettings
import
com
.
intellij
.
codeInsight
.
daemon
.
LineMarkerInfo
import
com
.
intellij
.
codeInsight
.
daemon
.
impl
.
DaemonCodeAnalyzerImpl
import
com
.
intellij
.
openapi
.
editor
.
Document
import
com
.
intellij
.
openapi
.
project
.
Project
import
com
.
intellij
.
openapi
.
util
.
io
.
FileUtil
import
com
.
intellij
.
psi
.
PsiDocumentManager
import
com
.
intellij
.
psi
.
PsiFile
import
com
.
intellij
.
rt
.
execution
.
junit
.
FileComparisonFailure
import
com
.
intellij
.
testFramework
.
ExpectedHighlightingData
import
com
.
intellij
.
testFramework
.
LightProjectDescriptor
import
com
.
intellij
.
testFramework
.
PlatformTestUtil
import
com
.
intellij
.
testFramework
.
UsefulTestCase
import
junit
.
framework
.
TestCase
import
org
.
jetbrains
.
kotlin
.
idea
.
highlighter
.
markers
.
TestableLineMarkerNavigator
import
org
.
jetbrains
.
kotlin
.
idea
.
navigation
.
NavigationTestUtils
import
org
.
jetbrains
.
kotlin
.
idea
.
test
.
ConfigLibraryUtil
import
org
.
jetbrains
.
kotlin
.
idea
.
test
.
KotlinLightCodeInsightFixtureTestCase
import
org
.
jetbrains
.
kotlin
.
idea
.
test
.
KotlinWithJdkAndRuntimeLightProjectDescriptor
import
org
.
jetbrains
.
kotlin
.
psi
.
KtFile
import
org
.
jetbrains
.
kotlin
.
test
.
InTextDirectivesUtils
import
org
.
jetbrains
.
kotlin
.
test
.
KotlinTestUtils
import
org
.
jetbrains
.
kotlin
.
test
.
TagsTestDataUtil
import
org
.
jetbrains
.
kotlin
.
test
.
util
.
renderAsGotoImplementation
import
org
.
junit
.
Assert
import
java
.
io
.
File
abstract
class
AbstractLineMarkersTest
:
KotlinLightCodeInsightFixtureTestCase
()
{
override
fun
getProjectDescriptor
():
LightProjectDescriptor
{
return
KotlinWithJdkAndRuntimeLightProjectDescriptor
.
INSTANCE
}
fun
doTest
(
path
:
String
)
=
doTest
(
path
)
{}
protected
fun
doAndCheckHighlighting
(
psiFile
:
PsiFile
,
documentToAnalyze
:
Document
,
expectedHighlighting
:
ExpectedHighlightingData
,
expectedFile
:
File
):
List
<
LineMarkerInfo
<*>>
{
myFixture
.
doHighlighting
()
return
checkHighlighting
(
psiFile
,
documentToAnalyze
,
expectedHighlighting
,
expectedFile
)
}
fun
doTest
(
path
:
String
,
additionalCheck
:
()
->
Unit
)
{
val
fileText
=
FileUtil
.
loadFile
(
testDataFile
())
try
{
ConfigLibraryUtil
.
configureLibrariesByDirective
(
myFixture
.
module
,
PlatformTestUtil
.
getCommunityPath
(),
fileText
)
if
(
InTextDirectivesUtils
.
findStringWithPrefixes
(
fileText
,
"METHOD_SEPARATORS"
)
!= null) {
DaemonCodeAnalyzerSettings
.
getInstance
().
SHOW_METHOD_SEPARATORS
=
true
}
myFixture
.
configureByFile
(
fileName
())
val
project
=
myFixture
.
project
val
document
=
myFixture
.
editor
.
document
val
data
=
ExpectedHighlightingData
(
document
,
false
,
false
,
false
)
data
.
init
()
PsiDocumentManager
.
getInstance
(
project
).
commitAllDocuments
()
val
markers
=
doAndCheckHighlighting
(
myFixture
.
file
,
document
,
data
,
testDataFile
())
assertNavigationElements
(
myFixture
.
project
,
myFixture
.
file
as
KtFile
,
markers
)
additionalCheck
()
}
catch
(
exc
:
Exception
)
{
throw
RuntimeException
(
exc
)
}
finally
{
ConfigLibraryUtil
.
unconfigureLibrariesByDirective
(
module
,
fileText
)
DaemonCodeAnalyzerSettings
.
getInstance
().
SHOW_METHOD_SEPARATORS
=
false
}
}
companion
object
{
@
Suppress
(
"SpellCheckingInspection"
)
private
const
val
LINE_MARKER_PREFIX
=
"LINEMARKER:"
private
const
val
TARGETS_PREFIX
=
"TARGETS"
fun
assertNavigationElements
(
project
:
Project
,
file
:
KtFile
,
markers
:
List
<
LineMarkerInfo
<*>>)
{
val
navigationDataComments
=
KotlinTestUtils
.
getLastCommentsInFile
(
file
,
KotlinTestUtils
.
CommentType
.
BLOCK_COMMENT
,
false
)
if
(
navigationDataComments
.
isEmpty
())
return
for
((
navigationCommentIndex
,
navigationComment
)
in
navigationDataComments
.
reversed
().
withIndex
())
{
val
description
=
getLineMarkerDescription
(
navigationComment
)
val
navigateMarkers
=
markers
.
filter
{
it
.
lineMarkerTooltip
?.
startsWith
(
description
)
==
true
}
val
navigateMarker
=
navigateMarkers
.
singleOrNull
()
?:
navigateMarkers
.
getOrNull
(
navigationCommentIndex
)
TestCase
.
assertNotNull
(
String
.
format
(
"Can't find marker for navigation check with description
\"
%s
\"
"
,
description
),
navigateMarker
)
val
handler
=
navigateMarker
!!.navigationHandler
if
(
handler
is
TestableLineMarkerNavigator
)
{
val
navigateElements
=
handler
.
getTargetsPopupDescriptor
(
navigateMarker
.
element
)?.
targets
?.
sortedBy
{
it
.
renderAsGotoImplementation
()
}
val
actualNavigationData
=
NavigationTestUtils
.
getNavigateElementsText
(
project
,
navigateElements
)
UsefulTestCase
.
assertSameLines
(
getExpectedNavigationText
(
navigationComment
),
actualNavigationData
)
}
else
{
Assert
.
fail
(
"Only TestableLineMarkerNavigator are supported in navigate check"
)
}
}
}
private
fun
getLineMarkerDescription
(
navigationComment
:
String
):
String
{
val
firstLineEnd
=
navigationComment
.
indexOf
(
"
\n
"
)
TestCase
.
assertTrue
(
"The first line in block comment must contain description of marker for navigation check"
,
firstLineEnd
!= -1
)
var
navigationMarkerText
=
navigationComment
.
substring
(
0
,
firstLineEnd
)
TestCase
.
assertTrue
(
String
.
format
(
"Add %s directive in first line of comment"
,
LINE_MARKER_PREFIX
),
navigationMarkerText
.
startsWith
(
LINE_MARKER_PREFIX
)
)
navigationMarkerText
=
navigationMarkerText
.
substring
(
LINE_MARKER_PREFIX
.
length
)
return
navigationMarkerText
.
trim
{
it
<=
' '
}
}
private
fun
getExpectedNavigationText
(
navigationComment
:
String
):
String
{
val
firstLineEnd
=
navigationComment
.
indexOf
(
"
\n
"
)
var
expectedNavigationText
=
navigationComment
.
substring
(
firstLineEnd
+
1
)
TestCase
.
assertTrue
(
String
.
format
(
"Marker %s is expected before navigation data"
,
TARGETS_PREFIX
),
expectedNavigationText
.
startsWith
(
TARGETS_PREFIX
)
)
expectedNavigationText
=
expectedNavigationText
.
substring
(
expectedNavigationText
.
indexOf
(
"
\n
"
)
+
1
)
return
expectedNavigationText
}
fun
checkHighlighting
(
psiFile
:
PsiFile
,
documentToAnalyze
:
Document
,
expectedHighlighting
:
ExpectedHighlightingData
,
expectedFile
:
File
):
MutableList
<
LineMarkerInfo
<*>>
{
val
markers
=
DaemonCodeAnalyzerImpl
.
getLineMarkers
(
documentToAnalyze
,
psiFile
.
project
)
try
{
expectedHighlighting
.
checkLineMarkers
(
psiFile
,
markers
,
documentToAnalyze
.
text
)
//
This
is
a
workaround
for
sad
bug
in
ExpectedHighlightingData
:
//
the
latter
doesn
't throw assertion error when some line markers are expected, but none are present.
if (FileUtil.loadFile(expectedFile).contains("<lineMarker") && markers.isEmpty()) {
throw AssertionError("Some line markers are expected, but nothing is present at all")
}
} catch (error: AssertionError) {
try {
val actualTextWithTestData = TagsTestDataUtil.insertInfoTags(markers, true, documentToAnalyze.text)
KotlinTestUtils.assertEqualsToFile(expectedFile, actualTextWithTestData)
} catch (failure: FileComparisonFailure) {
throw FileComparisonFailure(
error.message + "\n" + failure.message,
failure.expected,
failure.actual,
failure.filePath
)
}
}
return markers
}
}
}
idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractLineMarkersTestInLibrarySources.kt.202
0 → 100644
浏览文件 @
ff7576f8
/*
*
Copyright
2010
-
2019
JetBrains
s
.
r
.
o
.
and
Kotlin
Programming
Language
contributors
.
*
Use
of
this
source
code
is
governed
by
the
Apache
2.0
license
that
can
be
found
in
the
license
/
LICENSE
.
txt
file
.
*/
package
org
.
jetbrains
.
kotlin
.
idea
.
codeInsight
import
com
.
intellij
.
openapi
.
module
.
Module
import
com
.
intellij
.
openapi
.
roots
.
ModifiableRootModel
import
com
.
intellij
.
openapi
.
roots
.
OrderRootType
import
com
.
intellij
.
openapi
.
vfs
.
LocalFileSystem
import
com
.
intellij
.
openapi
.
vfs
.
VirtualFileManager
import
com
.
intellij
.
psi
.
PsiDocumentManager
import
com
.
intellij
.
testFramework
.
ExpectedHighlightingData
import
com
.
intellij
.
util
.
io
.
createFile
import
com
.
intellij
.
util
.
io
.
write
import
org
.
jetbrains
.
kotlin
.
idea
.
test
.
ConfigLibraryUtil
import
org
.
jetbrains
.
kotlin
.
idea
.
test
.
PluginTestCaseBase
import
org
.
jetbrains
.
kotlin
.
idea
.
test
.
SdkAndMockLibraryProjectDescriptor
import
org
.
jetbrains
.
kotlin
.
idea
.
util
.
ProjectRootsUtil
import
java
.
io
.
File
import
java
.
nio
.
file
.
Files
abstract
class
AbstractLineMarkersTestInLibrarySources
:
AbstractLineMarkersTest
()
{
private
var
libraryCleanPath
:
String
?
=
null
private
var
libraryClean
:
File
?
=
null
private
fun
getLibraryCleanPath
():
String
=
libraryCleanPath
!!
private
fun
getLibraryOriginalPath
():
String
=
PluginTestCaseBase
.
getTestDataPathBase
()
+
"/codeInsightInLibrary/_library"
override
fun
getProjectDescriptor
():
SdkAndMockLibraryProjectDescriptor
{
if
(
libraryCleanPath
==
null
)
{
val
libraryClean
=
Files
.
createTempDirectory
(
"lineMarkers_library"
)
val
libraryOriginal
=
File
(
getLibraryOriginalPath
())
libraryCleanPath
=
libraryClean
.
toString
()
for
(
file
in
libraryOriginal
.
walkTopDown
().
filter
{
!it.isDirectory }) {
val
text
=
file
.
readText
().
replace
(
"</?lineMarker.*?>"
.
toRegex
(),
""
)
val
cleanFile
=
libraryClean
.
resolve
(
file
.
relativeTo
(
libraryOriginal
).
path
)
cleanFile
.
createFile
()
cleanFile
.
write
(
text
)
}
this
.
libraryClean
=
File
(
libraryCleanPath
)
}
return
object
:
SdkAndMockLibraryProjectDescriptor
(
getLibraryCleanPath
(),
false
)
{
override
fun
configureModule
(
module
:
Module
,
model
:
ModifiableRootModel
)
{
super
.
configureModule
(
module
,
model
)
val
library
=
model
.
moduleLibraryTable
.
getLibraryByName
(
LIBRARY_NAME
)
!!
val
modifiableModel
=
library
.
modifiableModel
modifiableModel
.
addRoot
(
LocalFileSystem
.
getInstance
().
findFileByIoFile
(
libraryClean
!!)!!, OrderRootType.SOURCES)
modifiableModel
.
commit
()
}
}
}
fun
doTestWithLibrary
(
path
:
String
)
{
doTest
(
path
)
{
val
fileSystem
=
VirtualFileManager
.
getInstance
().
getFileSystem
(
"file"
)
val
libraryOriginal
=
File
(
getLibraryOriginalPath
())
val
project
=
myFixture
.
project
for
(
file
in
libraryOriginal
.
walkTopDown
().
filter
{
!it.isDirectory }) {
myFixture
.
openFileInEditor
(
fileSystem
.
findFileByPath
(
file
.
absolutePath
)
!!)
val
data
=
ExpectedHighlightingData
(
myFixture
.
editor
.
document
,
false
,
false
,
false
)
data
.
init
()
val
librarySourceFile
=
libraryClean
!!.resolve(file.relativeTo(libraryOriginal).path)
myFixture
.
openFileInEditor
(
fileSystem
.
findFileByPath
(
librarySourceFile
.
absolutePath
)
!!)
val
document
=
myFixture
.
editor
.
document
PsiDocumentManager
.
getInstance
(
project
).
commitAllDocuments
()
if
(
!ProjectRootsUtil.isLibrarySourceFile(project, myFixture.file.virtualFile)) {
throw
AssertionError
(
"File ${myFixture.file.virtualFile.path} should be in library sources!"
)
}
doAndCheckHighlighting
(
myFixture
.
file
,
document
,
data
,
file
)
}
}
}
override
fun
tearDown
()
{
libraryClean
?.
deleteRecursively
()
ConfigLibraryUtil
.
removeLibrary
(
module
,
SdkAndMockLibraryProjectDescriptor
.
LIBRARY_NAME
)
super
.
tearDown
()
}
}
\ No newline at end of file
idea/tests/org/jetbrains/kotlin/idea/highlighter/AbstractUsageHighlightingTest.kt.202
0 → 100644
浏览文件 @
ff7576f8
/*
*
Copyright
2010
-
2019
JetBrains
s
.
r
.
o
.
and
Kotlin
Programming
Language
contributors
.
*
Use
of
this
source
code
is
governed
by
the
Apache
2.0
license
that
can
be
found
in
the
license
/
LICENSE
.
txt
file
.
*/
package
org
.
jetbrains
.
kotlin
.
idea
.
highlighter
import
com
.
intellij
.
codeInsight
.
daemon
.
impl
.
HighlightInfo
import
com
.
intellij
.
codeInsight
.
daemon
.
impl
.
HighlightInfoType
import
com
.
intellij
.
codeInsight
.
highlighting
.
HighlightUsagesHandler
import
com
.
intellij
.
openapi
.
editor
.
colors
.
EditorColors
import
com
.
intellij
.
openapi
.
editor
.
colors
.
EditorColorsManager
import
com
.
intellij
.
openapi
.
editor
.
markup
.
RangeHighlighter
import
com
.
intellij
.
openapi
.
editor
.
markup
.
TextAttributes
import
com
.
intellij
.
testFramework
.
ExpectedHighlightingData
import
org
.
jetbrains
.
kotlin
.
idea
.
test
.*
abstract
class
AbstractUsageHighlightingTest
:
KotlinLightCodeInsightFixtureTestCase
()
{
companion
object
{
//
Not
standard
<
caret
>
to
leave
it
in
text
after
configureByFile
and
remove
manually
after
collecting
highlighting
information
const
val
CARET_TAG
=
"~"
}
protected
fun
doTest
(
unused
:
String
)
{
myFixture
.
configureByFile
(
fileName
())
val
document
=
myFixture
.
editor
.
document
val
data
=
ExpectedHighlightingData
(
document
,
false
,
false
,
true
,
false
)
data
.
init
()
val
caret
=
document
.
extractMarkerOffset
(
project
,
CARET_TAG
)
assert
(
caret
!= -1) { "Caret marker '$CARET_TAG' expected" }
editor
.
caretModel
.
moveToOffset
(
caret
)
HighlightUsagesHandler
.
invoke
(
project
,
editor
,
myFixture
.
file
)
val
highlighters
=
myFixture
.
editor
.
markupModel
.
allHighlighters
val
infos
=
highlighters
.
filter
{
isUsageHighlighting
(
it
)
}
.
map
{
highlighter
->
var
startOffset
=
highlighter
.
startOffset
var
endOffset
=
highlighter
.
endOffset
if
(
startOffset
>
caret
)
startOffset
+=
CARET_TAG
.
length
if
(
endOffset
>
caret
)
endOffset
+=
CARET_TAG
.
length
HighlightInfo
.
newHighlightInfo
(
HighlightInfoType
.
INFORMATION
)
.
range
(
startOffset
,
endOffset
)
.
create
()
}
data
.
checkResult
(
myFixture
.
file
,
infos
,
StringBuilder
(
document
.
text
).
insert
(
caret
,
CARET_TAG
).
toString
())
}
private
fun
isUsageHighlighting
(
info
:
RangeHighlighter
):
Boolean
{
val
globalScheme
=
EditorColorsManager
.
getInstance
().
globalScheme
val
readAttributes
:
TextAttributes
=
globalScheme
.
getAttributes
(
EditorColors
.
SEARCH_RESULT_ATTRIBUTES
)
val
writeAttributes
:
TextAttributes
=
globalScheme
.
getAttributes
(
EditorColors
.
WRITE_SEARCH_RESULT_ATTRIBUTES
)
return
info
.
textAttributes
==
readAttributes
||
info
.
textAttributes
==
writeAttributes
}
}
idea/tests/org/jetbrains/kotlin/idea/inspections/InspectionDescriptionTest.kt.202
0 → 100644
浏览文件 @
ff7576f8
/*
*
Copyright
2010
-
2019
JetBrains
s
.
r
.
o
.
and
Kotlin
Programming
Language
contributors
.
*
Use
of
this
source
code
is
governed
by
the
Apache
2.0
license
that
can
be
found
in
the
license
/
LICENSE
.
txt
file
.
*/
package
org
.
jetbrains
.
kotlin
.
idea
.
inspections
import
com
.
intellij
.
codeInspection
.
InspectionEP
import
com
.
intellij
.
codeInspection
.
InspectionProfileEntry
import
com
.
intellij
.
codeInspection
.
LocalInspectionEP
import
com
.
intellij
.
codeInspection
.
LocalInspectionTool
import
com
.
intellij
.
codeInspection
.
ex
.
InspectionToolRegistrar
import
com
.
intellij
.
codeInspection
.
ex
.
InspectionToolWrapper
import
com
.
intellij
.
openapi
.
extensions
.
Extensions
import
com
.
intellij
.
openapi
.
util
.
text
.
StringUtil
import
com
.
intellij
.
testFramework
.
LightPlatformTestCase
import
com
.
intellij
.
testFramework
.
UsefulTestCase
import
gnu
.
trove
.
THashMap
import
org
.
jetbrains
.
kotlin
.
idea
.
KotlinPluginUtil
import
org
.
jetbrains
.
kotlin
.
test
.
JUnit3WithIdeaConfigurationRunner
import
org
.
junit
.
runner
.
RunWith
@
RunWith
(
JUnit3WithIdeaConfigurationRunner
::
class
)
class
InspectionDescriptionTest
:
LightPlatformTestCase
()
{
fun
testDescriptionsAndShortNames
()
{
val
shortNames
=
THashMap
<
String
,
InspectionToolWrapper
<
InspectionProfileEntry
,
InspectionEP
>>()
val
inspectionTools
=
loadKotlinInspections
()
val
errors
=
StringBuilder
()
for
(
toolWrapper
in
inspectionTools
)
{
val
description
=
toolWrapper
.
loadDescription
()
if
(
description
==
null
)
{
errors
.
append
(
"description is null for inspection '"
).
append
(
desc
(
toolWrapper
))
}
val
shortName
=
toolWrapper
.
shortName
val
tool
=
shortNames
[
shortName
]
if
(
tool
!= null) {
errors
.
append
(
"Short names must be unique: "
+
shortName
+
"
\n
"
+
"inspection: '"
+
desc
(
tool
)
+
"
\n
"
+
" and '"
+
desc
(
toolWrapper
)
)
}
shortNames
.
put
(
shortName
,
toolWrapper
)
}
UsefulTestCase
.
assertEmpty
(
errors
.
toString
())
}
private
fun
loadKotlinInspections
():
List
<
InspectionToolWrapper
<
InspectionProfileEntry
,
InspectionEP
>>
{
return
InspectionToolRegistrar
.
getInstance
().
createTools
().
filter
{
it
.
extension
.
pluginDescriptor
.
pluginId
==
KotlinPluginUtil
.
KOTLIN_PLUGIN_ID
}
as
List
<
InspectionToolWrapper
<
InspectionProfileEntry
,
InspectionEP
>>
}
private
fun
loadKotlinInspectionExtensions
()
=
LocalInspectionEP
.
LOCAL_INSPECTION
.
extensions
.
filter
{
it
.
pluginDescriptor
.
pluginId
==
KotlinPluginUtil
.
KOTLIN_PLUGIN_ID
}
private
fun
desc
(
tool
:
InspectionToolWrapper
<
InspectionProfileEntry
,
InspectionEP
>):
String
{
return
tool
.
toString
()
+
" ('"
+
tool
.
descriptionContextClass
+
"') "
+
"in "
+
if
(
tool
.
extension
==
null
)
null
else
tool
.
extension
.
pluginDescriptor
}
fun
testExtensionPoints
()
{
val
shortNames
=
THashMap
<
String
,
LocalInspectionEP
>()
@
Suppress
(
"DEPRECATION"
)
val
inspectionEPs
=
Extensions
.
getExtensions
(
LocalInspectionEP
.
LOCAL_INSPECTION
)
val
tools
=
inspectionEPs
.
size
val
errors
=
StringBuilder
()
for
(
ep
in
inspectionEPs
)
{
val
shortName
=
ep
.
getShortName
()
val
ep1
=
shortNames
[
shortName
]
if
(
ep1
!= null) {
errors
.
append
(
"Short names must be unique: '"
+
shortName
+
"':
\n
"
+
"inspection: '"
+
ep1
.
implementationClass
+
"' in '"
+
ep1
.
pluginDescriptor
+
"'
\n
"
+
"; and '"
+
ep
.
implementationClass
+
"' in '"
+
ep
.
pluginDescriptor
+
"'"
)
}
shortNames
.
put
(
shortName
,
ep
)
}
println
(
"$tools inspection tools total via EP"
)
UsefulTestCase
.
assertEmpty
(
errors
.
toString
())
}
fun
testInspectionMappings
()
{
val
toolWrappers
=
loadKotlinInspections
()
val
errors
=
StringBuilder
()
toolWrappers
.
filter
({
toolWrapper
->
toolWrapper
.
extension
==
null
}).
forEach
{
toolWrapper
->
errors
.
append
(
"Please add XML mapping for "
).
append
(
toolWrapper
.
tool
::
class
.
java
)
}
UsefulTestCase
.
assertEmpty
(
errors
.
toString
())
}
fun
testMismatchedIds
()
{
val
failMessages
=
mutableListOf
<
String
>()
for
(
ep
in
loadKotlinInspectionExtensions
())
{
val
toolName
=
ep
.
implementationClass
val
tool
=
ep
.
instantiateTool
()
if
(
tool
is
LocalInspectionTool
)
{
checkValue
(
failMessages
,
toolName
,
"suppressId"
,
ep
.
id
,
ep
.
getShortName
(),
tool
.
id
)
checkValue
(
failMessages
,
toolName
,
"alternateId"
,
ep
.
alternativeId
,
null
,
tool
.
alternativeID
)
checkValue
(
failMessages
,
toolName
,
"shortName"
,
ep
.
getShortName
(),
null
,
tool
.
shortName
)
checkValue
(
failMessages
,
toolName
,
"runForWholeFile"
,
null
,
"false"
,
tool
.
runForWholeFile
().
toString
())
}
}
UsefulTestCase
.
assertEmpty
(
StringUtil
.
join
(
failMessages
,
"
\n
"
),
failMessages
)
}
fun
testNotEmptyToolNames
()
{
val
failMessages
=
mutableListOf
<
String
>()
for
(
ep
in
LocalInspectionEP
.
LOCAL_INSPECTION
.
extensions
)
{
val
toolName
=
ep
.
implementationClass
if
(
ep
.
getDisplayName
().
isNullOrEmpty
())
{
failMessages
.
add
(
toolName
+
": toolName is not set, tool won't be available in `run inspection` action"
)
}
}
UsefulTestCase
.
assertEmpty
(
failMessages
.
joinToString
(
"
\n
"
),
failMessages
)
}
private
fun
checkValue
(
failMessages
:
MutableCollection
<
String
>,
toolName
:
String
,
attributeName
:
String
,
xmlValue
:
String
?,
defaultXmlValue
:
String
?,
javaValue
:
String
?
)
{
if
(
StringUtil
.
isNotEmpty
(
xmlValue
))
{
if
(
javaValue
!= xmlValue) {
failMessages
.
add
(
"$toolName: mismatched $attributeName. Xml: $xmlValue; Java: $javaValue"
)
}
}
else
if
(
StringUtil
.
isNotEmpty
(
javaValue
))
{
if
(
javaValue
!= defaultXmlValue) {
failMessages
.
add
(
"$toolName: $attributeName overridden in wrong way, will work in tests only. Please set appropriate $attributeName value in XML ($javaValue)"
)
}
}
}
}
idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionDescriptionTest.kt.202
0 → 100644
浏览文件 @
ff7576f8
/*
*
Copyright
2010
-
2019
JetBrains
s
.
r
.
o
.
and
Kotlin
Programming
Language
contributors
.
*
Use
of
this
source
code
is
governed
by
the
Apache
2.0
license
that
can
be
found
in
the
license
/
LICENSE
.
txt
file
.
*/
package
org
.
jetbrains
.
kotlin
.
idea
.
intentions
import
com
.
intellij
.
codeInsight
.
intention
.
IntentionActionBean
import
com
.
intellij
.
codeInsight
.
intention
.
IntentionManager
import
com
.
intellij
.
codeInsight
.
intention
.
impl
.
config
.
IntentionManagerImpl
import
com
.
intellij
.
openapi
.
extensions
.
Extensions
import
com
.
intellij
.
testFramework
.
LightPlatformTestCase
import
com
.
intellij
.
testFramework
.
UsefulTestCase
import
org
.
jetbrains
.
kotlin
.
idea
.
KotlinPluginUtil
import
org
.
jetbrains
.
kotlin
.
test
.
JUnit3WithIdeaConfigurationRunner
import
org
.
junit
.
runner
.
RunWith
import
java
.
io
.
File
@
RunWith
(
JUnit3WithIdeaConfigurationRunner
::
class
)
class
IntentionDescriptionTest
:
LightPlatformTestCase
()
{
private
val
necessaryNormalNames
=
listOf
(
"description.html"
,
"before.kt.template"
,
"after.kt.template"
)
private
val
necessaryXmlNames
=
listOf
(
"description.html"
,
"before.xml.template"
,
"after.xml.template"
)
private
val
necessaryMavenNames
=
listOf
(
"description.html"
)
fun
testDescriptionsAndShortNames
()
{
val
intentionTools
=
loadKotlinIntentions
()
val
errors
=
StringBuilder
()
for
(
tool
in
intentionTools
)
{
val
className
=
tool
.
className
val
shortName
=
className
.
substringAfterLast
(
"."
).
replace
(
"$"
,
""
)
val
directory
=
File
(
"idea/resources-en/intentionDescriptions/$shortName"
)
if
(
!directory.exists() || !directory.isDirectory) {
if
(
tool
.
categories
!= null) {
errors
.
append
(
"No description directory for intention '"
).
append
(
className
).
append
(
"'
\n
"
)
}
}
else
{
val
necessaryNames
=
when
{
shortName
.
isMavenIntentionName
()
->
necessaryMavenNames
shortName
.
isXmlIntentionName
()
->
necessaryXmlNames
else
->
necessaryNormalNames
}
for
(
fileName
in
necessaryNames
)
{
val
file
=
directory
.
resolve
(
fileName
)
if
(
!file.exists() || !file.isFile) {
errors
.
append
(
"No description file $fileName for intention '"
).
append
(
className
).
append
(
"'
\n
"
)
}
}
}
}
UsefulTestCase
.
assertEmpty
(
errors
.
toString
())
}
private
fun
String
.
isMavenIntentionName
()
=
startsWith
(
"MavenPlugin"
)
private
fun
String
.
isXmlIntentionName
()
=
startsWith
(
"Add"
)
&&
endsWith
(
"ToManifest"
)
private
fun
loadKotlinIntentions
():
List
<
IntentionActionBean
>
{
val
extensionPoint
=
Extensions
.
getRootArea
().
getExtensionPoint
(
IntentionManagerImpl
.
EP_INTENTION_ACTIONS
)
return
extensionPoint
.
extensions
.
toList
().
filter
{
it
.
pluginDescriptor
.
pluginId
==
KotlinPluginUtil
.
KOTLIN_PLUGIN_ID
}
}
}
\ No newline at end of file
idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerTestUtil.kt.202
0 → 100644
浏览文件 @
ff7576f8
/*
*
Copyright
2010
-
2020
JetBrains
s
.
r
.
o
.
and
Kotlin
Programming
Language
contributors
.
*
Use
of
this
source
code
is
governed
by
the
Apache
2.0
license
that
can
be
found
in
the
license
/
LICENSE
.
txt
file
.
*/
package
org
.
jetbrains
.
kotlin
.
idea
.
slicer
import
com
.
intellij
.
analysis
.
AnalysisScope
import
com
.
intellij
.
ide
.
projectView
.
TreeStructureProvider
import
com
.
intellij
.
ide
.
util
.
treeView
.
AbstractTreeStructureBase
import
com
.
intellij
.
psi
.
search
.
GlobalSearchScope
import
com
.
intellij
.
psi
.
search
.
PsiSearchScopeUtil
import
com
.
intellij
.
slicer
.
DuplicateMap
import
com
.
intellij
.
slicer
.
SliceAnalysisParams
import
com
.
intellij
.
slicer
.
SliceNode
import
com
.
intellij
.
slicer
.
SliceRootNode
import
com
.
intellij
.
usages
.
TextChunk
import
org
.
jetbrains
.
kotlin
.
psi
.
KtFile
import
org
.
jetbrains
.
kotlin
.
psi
.
psiUtil
.
contains
import
org
.
jetbrains
.
kotlin
.
psi
.
psiUtil
.
startOffset
import
org
.
jetbrains
.
kotlin
.
test
.
InTextDirectivesUtils
import
java
.
awt
.
Font
internal
class
TestSliceTreeStructure
(
private
val
rootNode
:
SliceNode
)
:
AbstractTreeStructureBase
(
rootNode
.
project
)
{
override
fun
getProviders
()
=
emptyList
<
TreeStructureProvider
>()
override
fun
getRootElement
()
=
rootNode
override
fun
commit
()
{
}
override
fun
hasSomethingToCommit
()
=
false
}
internal
fun
buildTreeRepresentation
(
rootNode
:
SliceNode
):
String
{
val
project
=
rootNode
.
element
!!.project!!
val
projectScope
=
GlobalSearchScope
.
projectScope
(
project
)
fun
TextChunk
.
render
():
String
{
var
text
=
text
if
(
attributes
.
fontType
==
Font
.
BOLD
)
{
text
=
"<bold>$text</bold>"
}
return
text
}
fun
SliceNode
.
isSliceLeafValueClassNode
()
=
this
is
HackedSliceLeafValueClassNode
fun
process
(
node
:
SliceNode
,
indent
:
Int
):
String
{
val
usage
=
node
.
element
!!.value
node
.
calculateDupNode
()
val
isDuplicated
=
!node.isSliceLeafValueClassNode() && node.duplicate != null
return
buildString
{
when
{
node
is
SliceRootNode
&&
usage
.
element
is
KtFile
->
{
node
.
sortedChildren
.
forEach
{
append
(
process
(
it
,
indent
))
}
return
@
buildString
}
//
SliceLeafValueClassNode
is
package
-
private
node
.
isSliceLeafValueClassNode
()
->
append
(
"[${node.nodeText}]
\n
"
)
else
->
{
val
chunks
=
usage
.
text
if
(!PsiSearchScopeUtil.isInScope(projectScope, usage.element!!)
)
{
append
(
"LIB "
)
}
else
{
append
(
chunks
.
first
().
render
()
+
" "
)
}
repeat
(
indent
)
{
append
(
'\t'
)
}
if
(
usage
is
KotlinSliceDereferenceUsage
)
{
append
(
"DEREFERENCE: "
)
}
if
(
usage
is
KotlinSliceUsage
)
{
usage
.
mode
.
inlineCallStack
.
forEach
{
append
(
"(INLINE CALL ${it.function?.name}) "
)
}
usage
.
mode
.
behaviourStack
.
reversed
().
joinTo
(
this
,
separator
=
""
)
{
it
.
testPresentationPrefix
}
}
if
(
isDuplicated
)
{
append
(
"DUPLICATE: "
)
}
chunks
.
slice
(
1
until
chunks
.
size
).
joinTo
(
this
,
separator
=
""
)
{
it
.
render
()
}
KotlinSliceUsageCellRenderer
.
containerSuffix
(
usage
)?.
let
{
append
(
" ($it)"
)
}
append
(
"
\n
"
)
}
}
if
(
!isDuplicated) {
node
.
sortedChildren
.
forEach
{
append
(
process
(
it
,
indent
+
1
))
}
}
}.
replace
(
Regex
(
"</bold><bold>"
),
""
)
}
return
process
(
rootNode
,
0
)
}
private
val
SliceNode
.
sortedChildren
:
List
<
SliceNode
>
get
()
=
children
.
sortedBy
{
it
.
value
.
element
?.
startOffset
?:
-
1
}
internal
fun
testSliceFromOffset
(
file
:
KtFile
,
offset
:
Int
,
doTest
:
(
sliceProvider
:
KotlinSliceProvider
,
rootNode
:
SliceRootNode
)
->
Unit
)
{
val
fileText
=
file
.
text
val
flowKind
=
InTextDirectivesUtils
.
findStringWithPrefixes
(
fileText
,
"// FLOW: "
)
val
withDereferences
=
InTextDirectivesUtils
.
isDirectiveDefined
(
fileText
,
"// WITH_DEREFERENCES"
)
val
analysisParams
=
SliceAnalysisParams
().
apply
{
dataFlowToThis
=
when
(
flowKind
)
{
"IN"
->
true
"OUT"
->
false
else
->
throw
AssertionError
(
"Invalid flow kind: $flowKind"
)
}
showInstanceDereferences
=
withDereferences
scope
=
AnalysisScope
(
file
.
project
)
}
val
elementAtCaret
=
file
.
findElementAt
(
offset
)
!!
val
sliceProvider
=
KotlinSliceProvider
()
val
expression
=
sliceProvider
.
getExpressionAtCaret
(
elementAtCaret
,
analysisParams
.
dataFlowToThis
)
!!
val
rootUsage
=
sliceProvider
.
createRootUsage
(
expression
,
analysisParams
)
val
rootNode
=
SliceRootNode
(
file
.
project
,
DuplicateMap
(),
rootUsage
)
doTest
(
sliceProvider
,
rootNode
)
}
\ No newline at end of file
idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiHighlightingTest.kt.202
0 → 100644
浏览文件 @
ff7576f8
/*
*
Copyright
2010
-
2019
JetBrains
s
.
r
.
o
.
and
Kotlin
Programming
Language
contributors
.
*
Use
of
this
source
code
is
governed
by
the
Apache
2.0
license
that
can
be
found
in
the
license
/
LICENSE
.
txt
file
.
*/
package
org
.
jetbrains
.
kotlin
.
idea
.
stubs
import
com
.
intellij
.
codeInsight
.
daemon
.
impl
.
DaemonCodeAnalyzerImpl
import
com
.
intellij
.
codeInsight
.
daemon
.
impl
.
HighlightInfo
import
com
.
intellij
.
openapi
.
application
.
ApplicationManager
import
com
.
intellij
.
openapi
.
project
.
DumbService
import
com
.
intellij
.
psi
.
PsiDocumentManager
import
com
.
intellij
.
psi
.
impl
.
cache
.
CacheManager
import
com
.
intellij
.
psi
.
impl
.
source
.
tree
.
TreeElement
import
com
.
intellij
.
psi
.
impl
.
source
.
tree
.
TreeUtil
import
com
.
intellij
.
psi
.
search
.
GlobalSearchScope
import
com
.
intellij
.
psi
.
search
.
UsageSearchContext
import
com
.
intellij
.
testFramework
.
ExpectedHighlightingData
abstract
class
AbstractMultiHighlightingTest
:
AbstractMultiModuleTest
()
{
protected
open
val
shouldCheckLineMarkers
=
false
protected
open
val
shouldCheckResult
=
true
override
fun
checkHighlighting
(
data
:
ExpectedHighlightingData
):
Collection
<
HighlightInfo
>
{
data
.
init
()
PsiDocumentManager
.
getInstance
(
myProject
).
commitAllDocuments
()
//
to
load
text
ApplicationManager
.
getApplication
().
runWriteAction
{
TreeUtil
.
clearCaches
(
myFile
.
node
as
TreeElement
)
}
//
to
initialize
caches
if
(
!DumbService.isDumb(project)) {
CacheManager
.
SERVICE
.
getInstance
(
myProject
)
.
getFilesWithWord
(
"XXX"
,
UsageSearchContext
.
IN_COMMENTS
,
GlobalSearchScope
.
allScope
(
myProject
),
true
)
}
val
infos
=
doHighlighting
()
val
text
=
myEditor
.
document
.
text
if
(
shouldCheckLineMarkers
)
{
data
.
checkLineMarkers
(
myFile
,
DaemonCodeAnalyzerImpl
.
getLineMarkers
(
getDocument
(
file
),
project
),
text
)
}
if
(
shouldCheckResult
)
{
data
.
checkResult
(
myFile
,
infos
,
text
)
}
return
infos
}
}
\ No newline at end of file
jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt.202
浏览文件 @
ff7576f8
...
...
@@ -58,7 +58,6 @@ import org.jetbrains.kotlin.codegen.AsmUtil
import
org
.
jetbrains
.
kotlin
.
codegen
.
JvmCodegenUtil
import
org
.
jetbrains
.
kotlin
.
config
.
IncrementalCompilation
import
org
.
jetbrains
.
kotlin
.
config
.
KotlinCompilerVersion
.
TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY
import
org
.
jetbrains
.
kotlin
.
config
.
LanguageVersion
import
org
.
jetbrains
.
kotlin
.
incremental
.
components
.
LookupTracker
import
org
.
jetbrains
.
kotlin
.
incremental
.
withIC
import
org
.
jetbrains
.
kotlin
.
jps
.
build
.
KotlinJpsBuildTestBase
.
LibraryDependency
.*
...
...
@@ -464,6 +463,29 @@ open class KotlinJpsBuildTest : KotlinJpsBuildTestBase() {
buildAllModules
().
assertSuccessful
()
}
fun
testPureJavaProject
()
{
initProject
(
JVM_FULL_RUNTIME
)
fun
build
()
{
var
someFilesCompiled
=
false
buildCustom
(
CanceledStatus
.
NULL
,
TestProjectBuilderLogger
(),
BuildResult
())
{
project
.
setTestingContext
(
TestingContext
(
LookupTracker
.
DO_NOTHING
,
object
:
TestingBuildLogger
{
override
fun
compilingFiles
(
files
:
Collection
<
File
>,
allRemovedFilesFiles
:
Collection
<
File
>)
{
someFilesCompiled
=
true
}
}))
}
assertFalse
(
"Kotlin builder should return early if there are no Kotlin files"
,
someFilesCompiled
)
}
build
()
rename
(
"${workDir}/src/Test.java"
,
"Test1.java"
)
build
()
}
fun
testKotlinJavaProject
()
{
doTestWithRuntime
()
}
...
...
@@ -626,40 +648,6 @@ open class KotlinJpsBuildTest : KotlinJpsBuildTestBase() {
result
.
assertSuccessful
()
}
/*
*
Here
we
're checking that enabling inference in IDE doesn'
t
affect
compilation
via
JPS
*
*
the
following
two
tests
are
connected
:
*
-
testKotlinProjectWithEnabledNewInferenceInIDE
checks
that
project
is
compiled
when
new
inference
is
enabled
only
in
IDE
*
-
this
is
done
via
project
component
*
-
testKotlinProjectWithErrorsBecauseOfNewInference
checks
that
project
isn
't compiled when new inference is enabled in the compiler
*
* So, if the former will fail => option affects JPS compilation, it'
s
bad
.
Also
,
if
the
latter
test
fails
=>
test
is
useless
as
it
's
* compiled with new and old inference.
*
*/
fun testKotlinProjectWithEnabledNewInferenceInIDE() {
initProject(JVM_MOCK_RUNTIME)
val module = myProject.modules.single()
val args = module.kotlinCompilerArguments
args.languageVersion = LanguageVersion.KOTLIN_1_3.versionString
myProject.kotlinCommonCompilerArguments = args
buildAllModules().assertSuccessful()
}
fun testKotlinProjectWithErrorsBecauseOfNewInference() {
initProject(JVM_MOCK_RUNTIME)
val module = myProject.modules.single()
val args = module.kotlinCompilerArguments
args.newInference = true
myProject.kotlinCommonCompilerArguments = args
val result = buildAllModules()
result.assertFailed()
result.checkErrors()
}
private
fun
createKotlinJavaScriptLibraryArchive
()
{
val
jarFile
=
File
(
workDir
,
KOTLIN_JS_LIBRARY_JAR
)
try
{
...
...
plugins/uast-kotlin-idea/src/org/jetbrains/uast/kotlin/generate/KotlinUastCodeGenerationPlugin.kt.202
0 → 100644
浏览文件 @
ff7576f8
/*
*
Copyright
2010
-
2020
JetBrains
s
.
r
.
o
.
and
Kotlin
Programming
Language
contributors
.
*
Use
of
this
source
code
is
governed
by
the
Apache
2.0
license
that
can
be
found
in
the
license
/
LICENSE
.
txt
file
.
*/
package
org
.
jetbrains
.
uast
.
kotlin
.
generate
import
com
.
intellij
.
lang
.
Language
import
com
.
intellij
.
openapi
.
diagnostic
.
logger
import
com
.
intellij
.
openapi
.
project
.
Project
import
com
.
intellij
.
openapi
.
util
.
text
.
StringUtil
import
com
.
intellij
.
psi
.
PsiClassType
import
com
.
intellij
.
psi
.
PsiElement
import
com
.
intellij
.
psi
.
PsiType
import
com
.
intellij
.
psi
.
util
.
PsiTreeUtil
import
org
.
jetbrains
.
kotlin
.
idea
.
KotlinLanguage
import
org
.
jetbrains
.
kotlin
.
idea
.
caches
.
resolve
.
getResolutionFacade
import
org
.
jetbrains
.
kotlin
.
idea
.
core
.
KotlinNameSuggester
import
org
.
jetbrains
.
kotlin
.
idea
.
core
.
ShortenReferences
import
org
.
jetbrains
.
kotlin
.
idea
.
refactoring
.
fqName
.
fqName
import
org
.
jetbrains
.
kotlin
.
idea
.
util
.
getResolutionScope
import
org
.
jetbrains
.
kotlin
.
idea
.
util
.
resolveToKotlinType
import
org
.
jetbrains
.
kotlin
.
incremental
.
components
.
NoLookupLocation
import
org
.
jetbrains
.
kotlin
.
name
.
Name
import
org
.
jetbrains
.
kotlin
.
psi
.*
import
org
.
jetbrains
.
kotlin
.
psi
.
psiUtil
.*
import
org
.
jetbrains
.
kotlin
.
resolve
.
scopes
.
utils
.
findClassifier
import
org
.
jetbrains
.
kotlin
.
utils
.
addToStdlib
.
cast
import
org
.
jetbrains
.
kotlin
.
utils
.
addToStdlib
.
safeAs
import
org
.
jetbrains
.
uast
.*
import
org
.
jetbrains
.
uast
.
generate
.
UParameterInfo
import
org
.
jetbrains
.
uast
.
generate
.
UastCodeGenerationPlugin
import
org
.
jetbrains
.
uast
.
generate
.
UastElementFactory
import
org
.
jetbrains
.
uast
.
kotlin
.*
import
org
.
jetbrains
.
uast
.
kotlin
.
internal
.
KotlinFakeUElement
import
org
.
jetbrains
.
uast
.
kotlin
.
internal
.
toSourcePsiFakeAware
class
KotlinUastCodeGenerationPlugin
:
UastCodeGenerationPlugin
{
override
val
language
:
Language
get
()
=
KotlinLanguage
.
INSTANCE
override
fun
getElementFactory
(
project
:
Project
):
UastElementFactory
=
KotlinUastElementFactory
(
project
)
override
fun
<
T
:
UElement
>
replace
(
oldElement
:
UElement
,
newElement
:
T
,
elementType
:
Class
<
T
>):
T
?
{
val
oldPsi
=
oldElement
.
toSourcePsiFakeAware
().
singleOrNull
()
?:
return
null
val
newPsi
=
newElement
.
sourcePsi
?.
let
{
when
{
it
is
KtCallExpression
&&
it
.
parent
is
KtQualifiedExpression
->
it
.
parent
else
->
it
}
}
?:
return
null
val
psiFactory
=
KtPsiFactory
(
oldPsi
.
project
)
val
oldParentPsi
=
oldPsi
.
parent
val
(
updOldPsi
,
updNewPsi
)
=
when
{
oldParentPsi
is
KtStringTemplateExpression
&&
oldParentPsi
.
entries
.
size
==
1
->
oldParentPsi
to
newPsi
oldPsi
is
KtStringTemplateEntry
&&
newPsi
!is KtStringTemplateEntry && newPsi is KtExpression ->
oldPsi
to
psiFactory
.
createBlockStringTemplateEntry
(
newPsi
)
oldPsi
is
KtBlockExpression
&&
newPsi
is
KtBlockExpression
->
{
if
(!hasBraces(oldPsi) && hasBraces(newPsi)) {
oldPsi to psiFactory.createLambdaExpression("none", newPsi.statements.joinToString("\n") { "println()" }).bodyExpression!!.also {
it.statements.zip(newPsi.statements).forEach { it.first.replace(it.second) }
}
} else
oldPsi to newPsi
}
else ->
oldPsi to newPsi
}
return when (val replaced = updOldPsi.replace(updNewPsi)?.safeAs<KtElement>()?.let { ShortenReferences.DEFAULT.process(it) }) {
is KtCallExpression, is KtQualifiedExpression -> replaced.cast<KtExpression>().getPossiblyQualifiedCallExpression()
else -> replaced
}?.toUElementOfExpectedTypes(elementType)
}
}
private fun hasBraces(oldPsi: KtBlockExpression): Boolean = oldPsi.lBrace != null && oldPsi.rBrace != null
class KotlinUastElementFactory(project: Project) : UastElementFactory {
private val psiFactory = KtPsiFactory(project)
@Deprecated("use version with context parameter")
override fun createQualifiedReference(qualifiedName: String, context: UElement?): UQualifiedReferenceExpression? {
logger<KotlinUastElementFactory>().error("Please switch caller to the version with a context parameter")
return createQualifiedReference(qualifiedName, context?.sourcePsi)
}
/*override*/ fun createQualifiedReference(qualifiedName: String, context: PsiElement?): UQualifiedReferenceExpression? {
return psiFactory.createExpression(qualifiedName).let {
when (it) {
is KtDotQualifiedExpression -> KotlinUQualifiedReferenceExpression(it, null)
is KtSafeQualifiedExpression -> KotlinUSafeQualifiedExpression(it, null)
else -> null
}
}
}
override fun createCallExpression(
receiver: UExpression?,
methodName: String,
parameters: List<UExpression>,
expectedReturnType: PsiType?,
kind: UastCallKind,
context: PsiElement?
): UCallExpression? {
if (kind != UastCallKind.METHOD_CALL) return null
val typeParams = (context as? KtElement)?.let { kontext ->
val resolutionFacade = kontext.getResolutionFacade()
(expectedReturnType as? PsiClassType)?.parameters?.map { it.resolveToKotlinType(resolutionFacade) }
}
val name = methodName.quoteIfNeeded()
val methodCall = psiFactory.createExpression(
buildString {
if (receiver != null)
append("a.")
append(name)
if (typeParams != null) {
append(typeParams.joinToString(", ", "<", ">") { type ->
type.fqName?.asString() ?: ""
})
}
append("()")
}
).getPossiblyQualifiedCallExpression() ?: return null
if (receiver != null) {
methodCall.parent.safeAs<KtDotQualifiedExpression>()?.receiverExpression?.replace(wrapULiteral(receiver).sourcePsi!!)
}
val
valueArgumentList
=
methodCall
.
valueArgumentList
for
(
parameter
in
parameters
)
{
valueArgumentList
?.
addArgument
(
psiFactory
.
createArgument
(
wrapULiteral
(
parameter
).
sourcePsi
as
KtExpression
))
}
return
KotlinUFunctionCallExpression
(
methodCall
,
null
)
}
override
fun
createStringLiteralExpression
(
text
:
String
,
context
:
PsiElement
?):
ULiteralExpression
?
{
return
KotlinStringULiteralExpression
(
psiFactory
.
createExpression
(
StringUtil
.
wrapWithDoubleQuote
(
text
)),
null
)
}
override
fun
createNullLiteral
(
context
:
PsiElement
?):
ULiteralExpression
{
return
psiFactory
.
createExpression
(
"null"
).
toUElementOfType
<
ULiteralExpression
>()
!!
}
/*
override
*/
fun
createIntLiteral
(
value
:
Int
,
context
:
PsiElement
?):
ULiteralExpression
{
return
psiFactory
.
createExpression
(
value
.
toString
()).
toUElementOfType
<
ULiteralExpression
>()
!!
}
private
fun
KtExpression
.
ensureBlockExpressionBraces
():
KtExpression
{
if
(
this
!is KtBlockExpression || hasBraces(this)) return this
val
blockExpression
=
psiFactory
.
createBlock
(
this
.
statements
.
joinToString
(
"
\n
"
)
{
"println()"
})
for
((
placeholder
,
statement
)
in
blockExpression
.
statements
.
zip
(
this
.
statements
))
{
placeholder
.
replace
(
statement
)
}
return
blockExpression
}
@
Deprecated
(
"use version with context parameter"
)
fun
createIfExpression
(
condition
:
UExpression
,
thenBranch
:
UExpression
,
elseBranch
:
UExpression
?):
UIfExpression
?
{
logger
<
KotlinUastElementFactory
>().
error
(
"Please switch caller to the version with a context parameter"
)
return
createIfExpression
(
condition
,
thenBranch
,
elseBranch
,
null
)
}
override
fun
createIfExpression
(
condition
:
UExpression
,
thenBranch
:
UExpression
,
elseBranch
:
UExpression
?,
context
:
PsiElement
?
):
UIfExpression
?
{
val
conditionPsi
=
condition
.
sourcePsi
as
?
KtExpression
?:
return
null
val
thenBranchPsi
=
thenBranch
.
sourcePsi
as
?
KtExpression
?:
return
null
val
elseBranchPsi
=
elseBranch
?.
sourcePsi
as
?
KtExpression
return
KotlinUIfExpression
(
psiFactory
.
createIf
(
conditionPsi
,
thenBranchPsi
.
ensureBlockExpressionBraces
(),
elseBranchPsi
?.
ensureBlockExpressionBraces
()),
null
)
}
@
Deprecated
(
"use version with context parameter"
)
fun
createParenthesizedExpression
(
expression
:
UExpression
):
UParenthesizedExpression
?
{
logger
<
KotlinUastElementFactory
>().
error
(
"Please switch caller to the version with a context parameter"
)
return
createParenthesizedExpression
(
expression
,
null
)
}
override
fun
createParenthesizedExpression
(
expression
:
UExpression
,
context
:
PsiElement
?):
UParenthesizedExpression
?
{
val
source
=
expression
.
sourcePsi
?:
return
null
val
parenthesized
=
psiFactory
.
createExpression
(
"(${source.text})"
)
as
?
KtParenthesizedExpression
?:
return
null
return
KotlinUParenthesizedExpression
(
parenthesized
,
null
)
}
@
Deprecated
(
"use version with context parameter"
)
fun
createSimpleReference
(
name
:
String
):
USimpleNameReferenceExpression
?
{
logger
<
KotlinUastElementFactory
>().
error
(
"Please switch caller to the version with a context parameter"
)
return
createSimpleReference
(
name
,
null
)
}
override
fun
createSimpleReference
(
name
:
String
,
context
:
PsiElement
?):
USimpleNameReferenceExpression
?
{
return
KotlinUSimpleReferenceExpression
(
psiFactory
.
createSimpleName
(
name
),
null
)
}
@
Deprecated
(
"use version with context parameter"
)
fun
createSimpleReference
(
variable
:
UVariable
):
USimpleNameReferenceExpression
?
{
logger
<
KotlinUastElementFactory
>().
error
(
"Please switch caller to the version with a context parameter"
)
return
createSimpleReference
(
variable
,
null
)
}
override
fun
createSimpleReference
(
variable
:
UVariable
,
context
:
PsiElement
?):
USimpleNameReferenceExpression
?
{
return
createSimpleReference
(
variable
.
name
?:
return
null
,
context
)
}
@
Deprecated
(
"use version with context parameter"
)
fun
createReturnExpresion
(
expression
:
UExpression
?,
inLambda
:
Boolean
):
UReturnExpression
?
{
logger
<
KotlinUastElementFactory
>().
error
(
"Please switch caller to the version with a context parameter"
)
return
createReturnExpresion
(
expression
,
inLambda
,
null
)
}
override
fun
createReturnExpresion
(
expression
:
UExpression
?,
inLambda
:
Boolean
,
context
:
PsiElement
?):
UReturnExpression
?
{
val
label
=
if
(
inLambda
&&
context
!= null) getParentLambdaLabelName(context)?.let { "@$it" } ?: "" else ""
val
returnExpression
=
psiFactory
.
createExpression
(
"return$label 1"
)
as
KtReturnExpression
val
sourcePsi
=
expression
?.
sourcePsi
if
(
sourcePsi
!= null) {
returnExpression
.
returnedExpression
!!.replace(sourcePsi)
}
else
{
returnExpression
.
returnedExpression
?.
delete
()
}
return
KotlinUReturnExpression
(
returnExpression
,
null
)
}
private
fun
getParentLambdaLabelName
(
context
:
PsiElement
):
String
?
{
val
lambdaExpression
=
context
.
getParentOfType
<
KtLambdaExpression
>(
false
)
?:
return
null
lambdaExpression
.
parent
.
safeAs
<
KtLabeledExpression
>()?.
let
{
return
it
.
getLabelName
()
}
val
callExpression
=
lambdaExpression
.
getStrictParentOfType
<
KtCallExpression
>()
?:
return
null
callExpression
.
valueArguments
.
find
{
it
.
getArgumentExpression
()?.
unpackFunctionLiteral
(
allowParentheses
=
false
)
===
lambdaExpression
}
?:
return
null
return
callExpression
.
getCallNameExpression
()?.
text
}
@
Deprecated
(
"use version with context parameter"
)
fun
createBinaryExpression
(
leftOperand
:
UExpression
,
rightOperand
:
UExpression
,
operator
:
UastBinaryOperator
):
UBinaryExpression
?
{
logger
<
KotlinUastElementFactory
>().
error
(
"Please switch caller to the version with a context parameter"
)
return
createBinaryExpression
(
leftOperand
,
rightOperand
,
operator
,
null
)
}
override
fun
createBinaryExpression
(
leftOperand
:
UExpression
,
rightOperand
:
UExpression
,
operator
:
UastBinaryOperator
,
context
:
PsiElement
?
):
UBinaryExpression
?
{
val
binaryExpression
=
joinBinaryExpression
(
leftOperand
,
rightOperand
,
operator
)
?:
return
null
return
KotlinUBinaryExpression
(
binaryExpression
,
null
)
}
private
fun
joinBinaryExpression
(
leftOperand
:
UExpression
,
rightOperand
:
UExpression
,
operator
:
UastBinaryOperator
):
KtBinaryExpression
?
{
val
leftPsi
=
leftOperand
.
sourcePsi
?:
return
null
val
rightPsi
=
rightOperand
.
sourcePsi
?:
return
null
val
binaryExpression
=
psiFactory
.
createExpression
(
"a ${operator.text} b"
)
as
?
KtBinaryExpression
?:
return
null
binaryExpression
.
left
?.
replace
(
leftPsi
)
binaryExpression
.
right
?.
replace
(
rightPsi
)
return
binaryExpression
}
@
Deprecated
(
"use version with context parameter"
)
fun
createFlatBinaryExpression
(
leftOperand
:
UExpression
,
rightOperand
:
UExpression
,
operator
:
UastBinaryOperator
):
UPolyadicExpression
?
{
logger
<
KotlinUastElementFactory
>().
error
(
"Please switch caller to the version with a context parameter"
)
return
createFlatBinaryExpression
(
leftOperand
,
rightOperand
,
operator
,
null
)
}
override
fun
createFlatBinaryExpression
(
leftOperand
:
UExpression
,
rightOperand
:
UExpression
,
operator
:
UastBinaryOperator
,
context
:
PsiElement
?
):
UPolyadicExpression
?
{
fun
unwrapParentheses
(
exp
:
KtExpression
?)
{
if
(
exp
!is KtParenthesizedExpression) return
if
(!KtPsiUtil.areParenthesesUseless(exp)) return
exp.expression?.let { exp.replace(it) }
}
val binaryExpression = joinBinaryExpression(leftOperand, rightOperand, operator) ?: return null
unwrapParentheses(binaryExpression.left)
unwrapParentheses(binaryExpression.right)
return psiFactory.createExpression(binaryExpression.text).toUElementOfType()!!
}
@Deprecated("use version with context parameter")
fun createBlockExpression(expressions: List<UExpression>): UBlockExpression? {
logger<KotlinUastElementFactory>().error("Please switch caller to the version with a context parameter")
return createBlockExpression(expressions, null)
}
override fun createBlockExpression(expressions: List<UExpression>, context: PsiElement?): UBlockExpression? {
val sourceExpressions = expressions.flatMap { it.toSourcePsiFakeAware() }
val block = psiFactory.createBlock(
sourceExpressions.joinToString(separator = "\n") { "println()" }
)
for ((placeholder, psiElement) in block.statements.zip(sourceExpressions)) {
placeholder.replace(psiElement)
}
return KotlinUBlockExpression(block, null)
}
@Deprecated("use version with context parameter")
fun createDeclarationExpression(declarations: List<UDeclaration>): UDeclarationsExpression? {
logger<KotlinUastElementFactory>().error("Please switch caller to the version with a context parameter")
return createDeclarationExpression(declarations, null)
}
override fun createDeclarationExpression(declarations: List<UDeclaration>, context: PsiElement?): UDeclarationsExpression? {
return object : KotlinUDeclarationsExpression(null), KotlinFakeUElement {
override var declarations: List<UDeclaration> = declarations
override fun unwrapToSourcePsi(): List<PsiElement> = declarations.flatMap { it.toSourcePsiFakeAware() }
}
}
override fun createLambdaExpression(
parameters: List<UParameterInfo>,
body: UExpression,
context: PsiElement?
): ULambdaExpression? {
val resolutionFacade = (context as? KtElement)?.getResolutionFacade()
val validator = (context as? KtElement)?.let { usedNamesFilter(it) } ?: { true }
val newLambdaStatements = if (body is UBlockExpression) {
body.expressions.flatMap { member ->
when {
member is UReturnExpression -> member.returnExpression?.toSourcePsiFakeAware().orEmpty()
else -> member.toSourcePsiFakeAware()
}
}
} else
listOf(body.sourcePsi!!)
val
ktLambdaExpression
=
psiFactory
.
createLambdaExpression
(
parameters
.
joinToString
(
", "
)
{
p
->
val
ktype
=
resolutionFacade
?.
let
{
p
.
type
?.
resolveToKotlinType
(
it
)
}
StringBuilder
().
apply
{
append
(
p
.
suggestedName
?:
ktype
?.
let
{
KotlinNameSuggester
.
suggestNamesByType
(
it
,
validator
).
firstOrNull
()
})
?:
KotlinNameSuggester
.
suggestNameByName
(
"v"
,
validator
)
ktype
?.
fqName
?.
toString
()?.
let
{
append
(
": "
).
append
(
it
)
}
}
},
newLambdaStatements
.
joinToString
(
"
\n
"
)
{
"placeholder"
}
)
for
((
old
,
new
)
in
ktLambdaExpression
.
bodyExpression
!!.statements.zip(newLambdaStatements)) {
old
.
replace
(
new
)
}
return
ktLambdaExpression
.
toUElementOfType
()
!!
}
@
Deprecated
(
"use version with context parameter"
)
fun
createLambdaExpression
(
parameters
:
List
<
UParameterInfo
>,
body
:
UExpression
):
ULambdaExpression
?
{
logger
<
KotlinUastElementFactory
>().
error
(
"Please switch caller to the version with a context parameter"
)
return
createLambdaExpression
(
parameters
,
body
,
null
)
}
override
fun
createLocalVariable
(
suggestedName
:
String
?,
type
:
PsiType
?,
initializer
:
UExpression
,
immutable
:
Boolean
,
context
:
PsiElement
?
):
ULocalVariable
?
{
val
resolutionFacade
=
(
context
as
?
KtElement
)?.
getResolutionFacade
()
val
validator
=
(
context
as
?
KtElement
)?.
let
{
usedNamesFilter
(
it
)
}
?:
{
true
}
val
ktype
=
resolutionFacade
?.
let
{
type
?.
resolveToKotlinType
(
it
)
}
val
function
=
psiFactory
.
createFunction
(
buildString
{
append
(
"fun foo() { "
)
append
(
if
(
immutable
)
"val"
else
"var"
)
append
(
" "
)
append
(
suggestedName
?:
ktype
?.
let
{
KotlinNameSuggester
.
suggestNamesByType
(
it
,
validator
).
firstOrNull
()
})
?:
KotlinNameSuggester
.
suggestNameByName
(
"v"
,
validator
)
ktype
?.
fqName
?.
toString
()?.
let
{
append
(
": "
).
append
(
it
)
}
append
(
" = null"
)
append
(
"}"
)
}
)
val
ktVariable
=
PsiTreeUtil
.
findChildOfType
(
function
,
KtVariableDeclaration
::
class
.
java
)
!!
val
newVariable
=
ktVariable
.
initializer
!!.replace(initializer.sourcePsi!!).parent
return
newVariable
.
toUElementOfType
<
UVariable
>()
as
ULocalVariable
}
@
Deprecated
(
"use version with context parameter"
)
fun
createLocalVariable
(
suggestedName
:
String
?,
type
:
PsiType
?,
initializer
:
UExpression
,
immutable
:
Boolean
):
ULocalVariable
?
{
logger
<
KotlinUastElementFactory
>().
error
(
"Please switch caller to the version with a context parameter"
)
return
createLocalVariable
(
suggestedName
,
type
,
initializer
,
immutable
,
null
)
}
}
private
fun
usedNamesFilter
(
context
:
KtElement
):
(
String
)
->
Boolean
{
val
scope
=
context
.
getResolutionScope
()
return
{
name
:
String
->
scope
.
findClassifier
(
Name
.
identifier
(
name
),
NoLookupLocation
.
FROM_IDE
)
==
null
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录