diff --git a/annotations/com/intellij/codeInsight/template/annotations.xml b/annotations/com/intellij/codeInsight/template/annotations.xml
new file mode 100644
index 00000000000..49c52c9424a
--- /dev/null
+++ b/annotations/com/intellij/codeInsight/template/annotations.xml
@@ -0,0 +1,17 @@
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
\ No newline at end of file
diff --git a/annotations/com/intellij/codeInsight/template/impl/annotations.xml b/annotations/com/intellij/codeInsight/template/impl/annotations.xml
new file mode 100644
index 00000000000..76332fc8fde
--- /dev/null
+++ b/annotations/com/intellij/codeInsight/template/impl/annotations.xml
@@ -0,0 +1,34 @@
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
\ No newline at end of file
diff --git a/annotations/com/intellij/openapi/command/annotations.xml b/annotations/com/intellij/openapi/command/annotations.xml
new file mode 100644
index 00000000000..69318e5b241
--- /dev/null
+++ b/annotations/com/intellij/openapi/command/annotations.xml
@@ -0,0 +1,5 @@
+
+ -
+
+
+
\ No newline at end of file
diff --git a/annotations/com/intellij/psi/annotations.xml b/annotations/com/intellij/psi/annotations.xml
index 9ebf450d9bf..325cc901c25 100644
--- a/annotations/com/intellij/psi/annotations.xml
+++ b/annotations/com/intellij/psi/annotations.xml
@@ -11,6 +11,9 @@
-
+ -
+
+
-
@@ -18,4 +21,7 @@
name='com.intellij.psi.PsiReferenceService java.util.List<com.intellij.psi.PsiReference> getReferences(com.intellij.psi.PsiElement, com.intellij.psi.PsiReferenceService.Hints)'>
+ -
+
+
\ No newline at end of file
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTreeVisitorVoid.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTreeVisitorVoid.java
index 7958bb906e6..608ae63e6ac 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTreeVisitorVoid.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTreeVisitorVoid.java
@@ -17,10 +17,11 @@
package org.jetbrains.jet.lang.psi;
import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
public class JetTreeVisitorVoid extends JetVisitorVoid {
@Override
- public void visitElement(PsiElement element) {
+ public void visitElement(@NotNull PsiElement element) {
element.acceptChildren(this);
}
}
diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index 0ceff10bc59..4ec68bfe29b 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -257,6 +257,7 @@
+
diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/ShortenReferences.kt b/idea/src/org/jetbrains/jet/plugin/codeInsight/ShortenReferences.kt
index d461c5e474e..8a905069cee 100644
--- a/idea/src/org/jetbrains/jet/plugin/codeInsight/ShortenReferences.kt
+++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/ShortenReferences.kt
@@ -10,7 +10,6 @@ import org.jetbrains.jet.plugin.project.ResolveSessionForBodies;
import org.jetbrains.jet.plugin.quickfix.ImportInsertHelper;
import org.jetbrains.jet.renderer.DescriptorRenderer;
-import java.util.Collections;
import java.util.HashSet;
import com.intellij.psi.util.PsiTreeUtil
import java.util.ArrayList
@@ -18,22 +17,59 @@ import org.jetbrains.jet.lang.psi.psiUtil.getParentByType
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaPropertyDescriptor
import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyPackageFragmentForJavaClass
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaMethodDescriptor
+import com.intellij.openapi.util.TextRange
+import com.intellij.psi.SmartPointerManager
public object ShortenReferences {
public fun process(element: JetElement) {
- process(Collections.singleton(element))
+ process(listOf(element))
}
public fun process(elements: Iterable) {
- for ((file, fileElements) in elements.groupBy { element -> element.getContainingJetFile() }) {
+ process(elements, { FilterResult.PROCESS })
+ }
+
+ public fun process(file: JetFile, startOffset: Int, endOffset: Int) {
+ val smartPointerManager = SmartPointerManager.getInstance(file.getProject())
+ val pointer = smartPointerManager.createSmartPsiFileRangePointer(file, TextRange(startOffset, endOffset))
+ try{
+ process(listOf(file), { element ->
+ val segment = pointer.getRange()
+ if (segment != null) {
+ val range = TextRange(segment.getStartOffset(), segment.getEndOffset())
+ val elementRange = element.getTextRange()!!
+ when {
+ range.contains(elementRange) -> FilterResult.PROCESS
+ range.intersects(elementRange) -> FilterResult.GO_INSIDE
+ else -> FilterResult.SKIP
+ }
+ }
+ else{
+ FilterResult.SKIP
+ }
+ })
+ }
+ finally {
+ smartPointerManager.removePointer(pointer)
+ }
+ }
+
+ private enum class FilterResult {
+ SKIP
+ GO_INSIDE
+ PROCESS
+ }
+
+ private fun process(elements: Iterable, elementFilter: (PsiElement) -> FilterResult) {
+ for ((file, fileElements) in elements.groupBy { element -> element.getContainingFile() as JetFile }) {
// first resolve all qualified references - optimization
val referenceToContext = JetFileReferencesResolver.resolve(file, fileElements, visitShortNames = false)
- val shortenTypesVisitor = ShortenTypesVisitor(file, referenceToContext)
+ val shortenTypesVisitor = ShortenTypesVisitor(file, elementFilter, referenceToContext)
processElements(fileElements, shortenTypesVisitor)
shortenTypesVisitor.finish()
- processElements(fileElements, ShortenQualifiedExpressionsVisitor(file, referenceToContext))
+ processElements(fileElements, ShortenQualifiedExpressionsVisitor(file, elementFilter, referenceToContext))
}
}
@@ -43,7 +79,9 @@ public object ShortenReferences {
}
}
- private class ShortenTypesVisitor(val file: JetFile, val resolveMap: Map) : JetTreeVisitorVoid() {
+ private class ShortenTypesVisitor(val file: JetFile,
+ val elementFilter: (PsiElement) -> FilterResult,
+ val resolveMap: Map) : JetVisitorVoid() {
private val resolveSession : ResolveSessionForBodies
get() = AnalyzerFacadeWithCache.getLazyResolveSessionForFile(file)
@@ -57,10 +95,16 @@ public object ShortenReferences {
private fun bindingContext(expression: JetReferenceExpression): BindingContext = resolveMap[expression]!!
+ override fun visitElement(element: PsiElement) {
+ if (elementFilter(element) != FilterResult.SKIP) {
+ element.acceptChildren(this)
+ }
+ }
+
override fun visitUserType(userType: JetUserType) {
userType.getTypeArgumentList()?.accept(this)
- if (canShortenType(userType)) {
+ if (elementFilter(userType) == FilterResult.PROCESS && canShortenType(userType)) {
typesToShorten.add(userType)
}
else{
@@ -73,13 +117,13 @@ public object ShortenReferences {
val referenceExpression = userType.getReferenceExpression()
if (referenceExpression == null) return false
- val target = bindingContext(referenceExpression).get(BindingContext.REFERENCE_TARGET, referenceExpression)?.let { desc ->
+ val target = bindingContext(referenceExpression)[BindingContext.REFERENCE_TARGET, referenceExpression]?.let { desc ->
if (desc is ConstructorDescriptor) desc.getContainingDeclaration() else desc
}
if (target == null) return false
val typeReference = PsiTreeUtil.getParentOfType(userType, javaClass())!!
- val scope = resolveSession.resolveToElement(typeReference).get(BindingContext.TYPE_RESOLUTION_SCOPE, typeReference)!!
+ val scope = resolveSession.resolveToElement(typeReference)[BindingContext.TYPE_RESOLUTION_SCOPE, typeReference]!!
val name = target.getName()
val targetByName = scope.getClassifier(name)
if (targetByName == null) {
@@ -107,20 +151,27 @@ public object ShortenReferences {
}
}
- private class ShortenQualifiedExpressionsVisitor(val file: JetFile, val resolveMap: Map) : JetVisitorVoid() {
+ private class ShortenQualifiedExpressionsVisitor(val file: JetFile,
+ val elementFilter: (PsiElement) -> FilterResult,
+ val resolveMap: Map) : JetVisitorVoid() {
private val resolveSession : ResolveSessionForBodies
get() = AnalyzerFacadeWithCache.getLazyResolveSessionForFile(file)
private fun bindingContext(expression: JetReferenceExpression): BindingContext
= resolveMap[expression] ?: resolveSession.resolveToElement(expression) // binding context can be absent in the map if some references have been shortened already
- override fun visitJetElement(element: JetElement) {
- acceptChildren(element)
+ override fun visitElement(element: PsiElement) {
+ if (elementFilter(element) != FilterResult.SKIP) {
+ acceptChildren(element)
+ }
}
override fun visitDotQualifiedExpression(expression: JetDotQualifiedExpression) {
- val resultElement = processDotQualifiedExpression(expression)
- acceptChildren(resultElement)
+ val filterResult = elementFilter(expression)
+ val resultElement = if (filterResult == FilterResult.PROCESS) processDotQualifiedExpression(expression) else expression
+ if (filterResult != FilterResult.SKIP) {
+ acceptChildren(resultElement)
+ }
}
private fun processDotQualifiedExpression(qualifiedExpression: JetDotQualifiedExpression): PsiElement {
@@ -150,7 +201,7 @@ public object ShortenReferences {
bindingContext: BindingContext
): PsiElement {
val receiverExpression = qualifiedExpression.getReceiverExpression()
- val target = bindingContext.get(BindingContext.REFERENCE_TARGET, refExpression)
+ val target = bindingContext[BindingContext.REFERENCE_TARGET, refExpression]
if (target != null) {
if ((target is JavaPropertyDescriptor || target is JavaMethodDescriptor) && receiverExpression is JetDotQualifiedExpression) {
val containingDescriptor = target.getContainingDeclaration()
@@ -166,14 +217,14 @@ public object ShortenReferences {
private fun instantiatedClass(calleeExpression: JetReferenceExpression): ClassDescriptor? {
val bindingContext = bindingContext(calleeExpression)
- val target = bindingContext.get(BindingContext.REFERENCE_TARGET, calleeExpression)
+ val target = bindingContext[BindingContext.REFERENCE_TARGET, calleeExpression]
if (target != null) {
if (target is ConstructorDescriptor) {
return target.getContainingDeclaration()
}
}
else {
- val targets = bindingContext.get(BindingContext.AMBIGUOUS_REFERENCE_TARGET, calleeExpression)
+ val targets = bindingContext[BindingContext.AMBIGUOUS_REFERENCE_TARGET, calleeExpression]
if (targets != null && !targets.isEmpty()) {
var targetClass: ClassDescriptor? = null
for (descriptor in targets) {
@@ -220,10 +271,10 @@ public object ShortenReferences {
}
private fun resolveState(referenceExpression: JetReferenceExpression, bindingContext: BindingContext): Any? {
- val target = bindingContext.get(BindingContext.REFERENCE_TARGET, referenceExpression)
+ val target = bindingContext[BindingContext.REFERENCE_TARGET, referenceExpression]
if (target != null) return target.asString()
- val targets = bindingContext.get(BindingContext.AMBIGUOUS_REFERENCE_TARGET, referenceExpression)
+ val targets = bindingContext[BindingContext.AMBIGUOUS_REFERENCE_TARGET, referenceExpression]
if (targets != null) return HashSet(targets.map{it.asString()})
return null
diff --git a/idea/src/org/jetbrains/jet/plugin/completion/smart/LambdaItems.kt b/idea/src/org/jetbrains/jet/plugin/completion/smart/LambdaItems.kt
index 14c28729ad4..f91f63b204e 100644
--- a/idea/src/org/jetbrains/jet/plugin/completion/smart/LambdaItems.kt
+++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/LambdaItems.kt
@@ -8,6 +8,12 @@ import org.jetbrains.jet.renderer.DescriptorRenderer
import org.jetbrains.jet.plugin.refactoring.JetNameValidator
import org.jetbrains.jet.plugin.refactoring.JetNameSuggester
import com.intellij.openapi.project.Project
+import com.intellij.codeInsight.completion.InsertHandler
+import com.intellij.codeInsight.completion.InsertionContext
+import com.intellij.codeInsight.template.*
+import com.intellij.openapi.command.CommandProcessor
+import com.intellij.openapi.application.ApplicationManager
+import com.intellij.openapi.util.Computable
class LambdaItems(val project: Project) {
public fun addToCollection(collection: MutableCollection, functionExpectedInfos: Collection) {
@@ -27,35 +33,104 @@ class LambdaItems(val project: Project) {
}
if (singleSignatureLength != 0) {
- fun functionParameterTypes(functionType: JetType)
- = KotlinBuiltIns.getInstance().getParameterTypeProjectionsFromFunctionType(functionType).map { it.getType() }
-
for (functionType in distinctTypes) {
val parameterTypes = functionParameterTypes(functionType)
val parametersPresentation = parameterTypes.map { DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(it) }.makeString(", ")
-
val useExplicitTypes = distinctTypes.stream().any { it != functionType && functionParameterTypes(it).size == parameterTypes.size }
- val nameValidator = JetNameValidator.getEmptyValidator(project)
-
- fun parameterName(parameterType: JetType) = JetNameSuggester.suggestNames(parameterType, nameValidator, "p")[0]
-
- fun parameterText(parameterType: JetType): String {
- return if (useExplicitTypes)
- parameterName(parameterType) + ": " + DescriptorRenderer.SOURCE_CODE.renderType(parameterType)
- else
- parameterName(parameterType)
- }
-
- val parametersText = parameterTypes.map(::parameterText).makeString(", ")
-
- val useParenthesis = parameterTypes.size != 1
- fun wrap(s: String) = if (useParenthesis) "($s)" else s
+ fun wrap(s: String) = if (useParenthesis(useExplicitTypes, parameterTypes)) "($s)" else s
val lookupString = "{ ${wrap(parametersPresentation)} -> ... }"
- val lookupElement = createLookupElement(lookupString, "{ ${wrap(parametersText)} -> ", " }", shortenRefs = true)
+
+ val lookupElement = LookupElementBuilder.create(lookupString)
+ .withInsertHandler(LambdaInsertHandler(functionType, useExplicitTypes))
+ .suppressAutoInsertion()
collection.add(addTailToLookupElement(lookupElement, functionExpectedInfos.filter { it.`type` == functionType }))
}
}
}
-}
\ No newline at end of file
+
+ private fun useParenthesis(useExplicitTypes: Boolean, parameterTypes: List) = useExplicitTypes || parameterTypes.size != 1
+
+ private inner class LambdaInsertHandler(val functionType: JetType, val useExplicitTypes: Boolean) : InsertHandler {
+ override fun handleInsert(context: InsertionContext, item: LookupElement) {
+ val document = context.getDocument()
+ val editor = context.getEditor()
+ val offset = context.getStartOffset()
+ val placeholder = "{}"
+ document.replaceString(offset, context.getTailOffset(), placeholder)
+ editor.getCaretModel().moveToOffset(offset + 1)
+ val rangeMarker = document.createRangeMarker(offset, offset + placeholder.length)
+
+ // we start template later to not interfere with insertion of tail type
+ val commandProcessor = CommandProcessor.getInstance()
+ val commandName = commandProcessor.getCurrentCommandName()
+ val commandGroupId = commandProcessor.getCurrentCommandGroupId()
+ context.setLaterRunnable{
+ commandProcessor.executeCommand(project, {
+ ApplicationManager.getApplication()!!.runWriteAction(Computable{
+ try{
+ if (rangeMarker.isValid()) {
+ document.deleteString(rangeMarker.getStartOffset(), rangeMarker.getEndOffset())
+ editor.getCaretModel().moveToOffset(rangeMarker.getStartOffset())
+ TemplateManager.getInstance(project).startTemplate(editor, buildTemplate())
+ }
+ }
+ finally {
+ rangeMarker.dispose()
+ }
+ })
+ }, commandName, commandGroupId)
+ }
+ }
+
+ private fun buildTemplate(): Template {
+ val parameterTypes = functionParameterTypes(functionType)
+
+ val nameValidator = JetNameValidator.getEmptyValidator(project) //TODO: check for names in scope
+
+ val useParenthesis = useParenthesis(useExplicitTypes, parameterTypes)
+
+ val manager = TemplateManager.getInstance(project)
+
+ val template = manager.createTemplate("", "")
+ template.setToShortenLongNames(true)
+ //template.setToReformat(true) //TODO
+ template.addTextSegment("{ ")
+ if (useParenthesis) {
+ template.addTextSegment("(")
+ }
+
+ var i = 0
+ for (parameterType in parameterTypes) {
+ if (i++ > 0) {
+ template.addTextSegment(", ")
+ }
+ template.addVariable(ParameterNameExpression(JetNameSuggester.suggestNames(parameterType, nameValidator, "p")), true)
+ if (useExplicitTypes) {
+ template.addTextSegment(": " + DescriptorRenderer.SOURCE_CODE.renderType(parameterType))
+ }
+ }
+
+ if (useParenthesis) {
+ template.addTextSegment(")")
+ }
+ template.addTextSegment(" -> ")
+ template.addEndVariable()
+ template.addTextSegment(" }")
+ return template
+ }
+ }
+
+ private fun functionParameterTypes(functionType: JetType): List
+ = KotlinBuiltIns.getInstance().getParameterTypeProjectionsFromFunctionType(functionType).map { it.getType() }
+
+ private class ParameterNameExpression(val nameSuggestions: Array) : Expression() {
+ override fun calculateResult(context: ExpressionContext?) = TextResult(nameSuggestions[0])
+
+ override fun calculateQuickResult(context: ExpressionContext?): Result? = null
+
+ override fun calculateLookupItems(context: ExpressionContext?)
+ = Array(nameSuggestions.size, { LookupElementBuilder.create(nameSuggestions[it]) })
+ }
+}
diff --git a/idea/src/org/jetbrains/jet/plugin/completion/smart/StaticMembers.kt b/idea/src/org/jetbrains/jet/plugin/completion/smart/StaticMembers.kt
index 7384092d3f8..f5deeb827e6 100644
--- a/idea/src/org/jetbrains/jet/plugin/completion/smart/StaticMembers.kt
+++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/StaticMembers.kt
@@ -48,7 +48,7 @@ class StaticMembers(val bindingContext: BindingContext, val resolveSession: Reso
val matchedExpectedInfos = expectedInfos.filter {
expectedInfo ->
descriptor is CallableDescriptor && descriptor.getReturnType()?.let { it.isSubtypeOf(expectedInfo.`type`) } ?: false
- || descriptor is ClassDescriptor && descriptor.getKind() == ClassKind.ENUM_ENTRY
+ || DescriptorUtils.isEnumEntry(descriptor) /* we do not need to check type of enum entry because it's taken from proper enum */
}
if (matchedExpectedInfos.isEmpty()) return
diff --git a/idea/src/org/jetbrains/jet/plugin/completion/smart/Utils.kt b/idea/src/org/jetbrains/jet/plugin/completion/smart/Utils.kt
index cb0331796fe..b9d9bbfa3bb 100644
--- a/idea/src/org/jetbrains/jet/plugin/completion/smart/Utils.kt
+++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/Utils.kt
@@ -34,11 +34,7 @@ class ArtificialElementInsertHandler(
fun shortenReferences(context: InsertionContext, startOffset: Int, endOffset: Int) {
PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments();
- val file = context.getFile() as JetFile
- val element = PsiTreeUtil.findElementOfClassAtRange(file, startOffset, endOffset, javaClass())
- if (element != null) {
- ShortenReferences.process(element)
- }
+ ShortenReferences.process(context.getFile() as JetFile, startOffset, endOffset)
}
fun mergeTails(tails: Collection): Tail? {
diff --git a/idea/src/org/jetbrains/jet/plugin/imports/KotlinImportOptimizer.kt b/idea/src/org/jetbrains/jet/plugin/imports/KotlinImportOptimizer.kt
index 83d55c6b795..0a5b3f97f38 100644
--- a/idea/src/org/jetbrains/jet/plugin/imports/KotlinImportOptimizer.kt
+++ b/idea/src/org/jetbrains/jet/plugin/imports/KotlinImportOptimizer.kt
@@ -74,7 +74,7 @@ public class KotlinImportOptimizer() : ImportOptimizer {
private fun extractUsedQualifiedNames(jetFile: JetFile): Set {
val usedQualifiedNames = HashSet()
jetFile.accept(object : JetVisitorVoid() {
- override fun visitElement(element: PsiElement?) {
+ override fun visitElement(element: PsiElement) {
ProgressIndicatorProvider.checkCanceled()
element?.acceptChildren(this)
}
diff --git a/idea/src/org/jetbrains/jet/plugin/inspections/IntentionBasedInspection.kt b/idea/src/org/jetbrains/jet/plugin/inspections/IntentionBasedInspection.kt
index 4802df3181b..60860553479 100644
--- a/idea/src/org/jetbrains/jet/plugin/inspections/IntentionBasedInspection.kt
+++ b/idea/src/org/jetbrains/jet/plugin/inspections/IntentionBasedInspection.kt
@@ -35,7 +35,7 @@ public abstract class IntentionBasedInspection(
) : AbstractKotlinInspection() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
return object: PsiElementVisitor() {
- override fun visitElement(element: PsiElement?) {
+ override fun visitElement(element: PsiElement) {
if (!intention.elementType.isInstance(element)) return
[suppress("UNCHECKED_CAST")]
diff --git a/idea/src/org/jetbrains/jet/plugin/liveTemplates/KotlinShortenFQNamesProcessor.kt b/idea/src/org/jetbrains/jet/plugin/liveTemplates/KotlinShortenFQNamesProcessor.kt
new file mode 100644
index 00000000000..e0df888a5d7
--- /dev/null
+++ b/idea/src/org/jetbrains/jet/plugin/liveTemplates/KotlinShortenFQNamesProcessor.kt
@@ -0,0 +1,38 @@
+package org.jetbrains.jet.plugin.liveTemplates
+
+import com.intellij.codeInsight.template.impl.TemplateOptionalProcessor
+import com.intellij.openapi.project.Project
+import com.intellij.codeInsight.template.Template
+import com.intellij.openapi.editor.Document
+import com.intellij.openapi.editor.RangeMarker
+import com.intellij.openapi.editor.Editor
+import com.intellij.codeInsight.CodeInsightBundle
+import com.intellij.psi.PsiDocumentManager
+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences
+import com.intellij.psi.util.PsiUtilBase
+import org.jetbrains.jet.lang.psi.JetFile
+
+public class KotlinShortenFQNamesProcessor : TemplateOptionalProcessor {
+ override fun processText(project: Project, template: Template, document: Document, templateRange: RangeMarker, editor: Editor) {
+ if (!template.isToShortenLongNames()) return
+
+ PsiDocumentManager.getInstance(project).commitDocument(document)
+
+ val file = PsiUtilBase.getPsiFileInEditor(editor, project) as? JetFile ?: return
+ ShortenReferences.process(file, templateRange.getStartOffset(), templateRange.getEndOffset())
+
+ PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document)
+ }
+
+ override fun getOptionName(): String {
+ return CodeInsightBundle.message("dialog.edit.template.checkbox.shorten.fq.names")!!
+ }
+
+ override fun isEnabled(template: Template) = template.isToShortenLongNames()
+
+ override fun setEnabled(template: Template, value: Boolean) {
+ template.setToShortenLongNames(value)
+ }
+
+ override fun isVisible(template: Template) = true
+}
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameValidator.java b/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameValidator.java
index f4fa4ab4ae1..ee2dbabe95c 100644
--- a/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameValidator.java
+++ b/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameValidator.java
@@ -39,7 +39,7 @@ public abstract class JetNameValidator {
};
}
- @NotNull
+ @NotNull //TODO: shouldn't it be "createCollectingValidator"?
public static JetNameValidator getCollectingValidator(final Project project) {
return new JetNameValidator(project) {
private final Set suggestedSet = new HashSet();
diff --git a/idea/testData/completion/handlers/smart/LambdaInsertImport.kt b/idea/testData/completion/handlers/smart/LambdaInsertImport.kt
new file mode 100644
index 00000000000..859d73a97b0
--- /dev/null
+++ b/idea/testData/completion/handlers/smart/LambdaInsertImport.kt
@@ -0,0 +1,8 @@
+fun foo(p: (java.util.Date) -> Unit){}
+fun foo(p: (String) -> Unit){}
+
+fun bar() {
+ foo()
+}
+
+// ELEMENT: "{ (Date) -> ... }"
diff --git a/idea/testData/completion/handlers/smart/LambdaInsertImport.kt.after b/idea/testData/completion/handlers/smart/LambdaInsertImport.kt.after
new file mode 100644
index 00000000000..3715f6d4194
--- /dev/null
+++ b/idea/testData/completion/handlers/smart/LambdaInsertImport.kt.after
@@ -0,0 +1,10 @@
+import java.util.Date
+
+fun foo(p: (java.util.Date) -> Unit){}
+fun foo(p: (String) -> Unit){}
+
+fun bar() {
+ foo({ (date: Date) -> })
+}
+
+// ELEMENT: "{ (Date) -> ... }"
diff --git a/idea/testData/completion/smart/Lambda4.kt b/idea/testData/completion/smart/Lambda4.kt
index 57e9058c189..4079b76b003 100644
--- a/idea/testData/completion/smart/Lambda4.kt
+++ b/idea/testData/completion/smart/Lambda4.kt
@@ -6,5 +6,5 @@ fun bar() {
}
// ABSENT: "{...}"
-// EXIST: "{ String -> ... }"
-// EXIST: "{ Int -> ... }"
+// EXIST: "{ (String) -> ... }"
+// EXIST: "{ (Int) -> ... }"
diff --git a/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java
index 076bc1e17e7..7a2b55e0e46 100644
--- a/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java
+++ b/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java
@@ -221,6 +221,11 @@ public class SmartCompletionHandlerTestGenerated extends AbstractSmartCompletion
doTest("idea/testData/completion/handlers/smart/Lambda5.kt");
}
+ @TestMetadata("LambdaInsertImport.kt")
+ public void testLambdaInsertImport() throws Exception {
+ doTest("idea/testData/completion/handlers/smart/LambdaInsertImport.kt");
+ }
+
@TestMetadata("MergeTail1.kt")
public void testMergeTail1() throws Exception {
doTest("idea/testData/completion/handlers/smart/MergeTail1.kt");