diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/DelegatingIntentionAction.kt b/idea/src/org/jetbrains/jet/plugin/quickfix/DelegatingIntentionAction.kt new file mode 100644 index 00000000000..bb8a00a5993 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/DelegatingIntentionAction.kt @@ -0,0 +1,5 @@ +package org.jetbrains.jet.plugin.quickfix + +import com.intellij.codeInsight.intention.IntentionAction + +public open class DelegatingIntentionAction(val delegate: IntentionAction): IntentionAction by delegate diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/createFromUsage/createClass/CreateClassFromReferenceExpressionActionFactory.kt b/idea/src/org/jetbrains/jet/plugin/quickfix/createFromUsage/createClass/CreateClassFromReferenceExpressionActionFactory.kt index afb205661f6..8a9bc93a594 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/createFromUsage/createClass/CreateClassFromReferenceExpressionActionFactory.kt +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/createFromUsage/createClass/CreateClassFromReferenceExpressionActionFactory.kt @@ -23,6 +23,11 @@ import org.jetbrains.jet.lang.psi.JetReferenceExpression import java.util.Arrays import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression import org.jetbrains.jet.lang.psi.psiUtil.isDotReceiver +import com.intellij.codeInsight.daemon.quickFix.CreateClassOrPackageFix +import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor +import org.jetbrains.jet.lang.resolve.name.FqName +import java.util.ArrayList +import org.jetbrains.jet.utils.addToStdlib.singletonOrEmptyList public object CreateClassFromReferenceExpressionActionFactory : JetIntentionActionsFactory() { override fun doCreateActions(diagnostic: Diagnostic): List { @@ -32,7 +37,6 @@ public object CreateClassFromReferenceExpressionActionFactory : JetIntentionActi val file = refExpr.getContainingFile() as? JetFile ?: return Collections.emptyList() val name = refExpr.getReferencedName() - if (!name.checkClassName()) return Collections.emptyList() val exhaust = refExpr.getAnalysisResults() val context = exhaust.getBindingContext() @@ -56,7 +60,10 @@ public object CreateClassFromReferenceExpressionActionFactory : JetIntentionActi getTargetParentByQualifier(refExpr.getContainingJetFile(), receiverSelector != null, qualifierDescriptor) ?: return Collections.emptyList() - return ClassKind.values() + val createPackageAction = refExpr.getCreatePackageFixIfApplicable(targetParent) + if (createPackageAction != null) return Collections.singletonList(createPackageAction) + + return (if (name.checkClassName()) ClassKind.values() else array()) .filter { when (it) { ClassKind.ANNOTATION_CLASS -> inImport diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/createFromUsage/createClass/CreateClassFromTypeReferenceActionFactory.kt b/idea/src/org/jetbrains/jet/plugin/quickfix/createFromUsage/createClass/CreateClassFromTypeReferenceActionFactory.kt index 8b306cd1190..307b7360dbb 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/createFromUsage/createClass/CreateClassFromTypeReferenceActionFactory.kt +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/createFromUsage/createClass/CreateClassFromTypeReferenceActionFactory.kt @@ -8,22 +8,20 @@ import java.util.Collections import org.jetbrains.jet.lang.psi.JetUserType import org.jetbrains.jet.lang.psi.JetFile import org.jetbrains.jet.lang.resolve.BindingContext -import org.jetbrains.jet.plugin.caches.resolve.getAnalysisResults import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.TypeInfo import org.jetbrains.jet.lang.types.Variance -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor -import com.intellij.psi.PsiElement import org.jetbrains.jet.lang.psi.JetDelegatorToSuperClass -import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall import org.jetbrains.jet.lang.psi.JetConstructorCalleeExpression import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache +import org.jetbrains.jet.utils.addToStdlib.singletonOrEmptyList public object CreateClassFromTypeReferenceActionFactory: JetIntentionActionsFactory() { override fun doCreateActions(diagnostic: Diagnostic): List { val userType = QuickFixUtil.getParentElementOfType(diagnostic, javaClass()) ?: return Collections.emptyList() val typeArguments = userType.getTypeArgumentsAsTypes() - val name = userType.getReferencedName() ?: return Collections.emptyList() + val refExpr = userType.getReferenceExpression() ?: return Collections.emptyList() + val name = refExpr.getReferencedName() val typeRefParent = userType.getParent()?.getParent() if (typeRefParent is JetConstructorCalleeExpression) return Collections.emptyList() @@ -54,7 +52,8 @@ public object CreateClassFromTypeReferenceActionFactory: JetIntentionActionsFact } } - return possibleKinds.map { + val createPackageAction = refExpr.getCreatePackageFixIfApplicable(targetParent) + val createClassActions = possibleKinds.map { val classInfo = ClassInfo( kind = it, name = name, @@ -64,5 +63,6 @@ public object CreateClassFromTypeReferenceActionFactory: JetIntentionActionsFact ) CreateClassFromUsageFix(userType, classInfo) } + return createPackageAction.singletonOrEmptyList() + createClassActions } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/createFromUsage/createClass/createClassUtils.kt b/idea/src/org/jetbrains/jet/plugin/quickfix/createFromUsage/createClass/createClassUtils.kt index deae306e39b..92ba8106b28 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/createFromUsage/createClass/createClassUtils.kt +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/createFromUsage/createClass/createClassUtils.kt @@ -6,9 +6,7 @@ import com.intellij.psi.PsiElement import org.jetbrains.jet.lang.descriptors.ClassDescriptor import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil -import com.intellij.openapi.module.ModuleUtilCore import com.intellij.psi.JavaPsiFacade -import org.jetbrains.jet.lang.psi.JetElement import org.jetbrains.jet.lang.psi.JetExpression import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.guessTypes import org.jetbrains.jet.lang.resolve.BindingContext @@ -21,16 +19,23 @@ import org.jetbrains.jet.lang.types.Variance import org.jetbrains.jet.lang.psi.Call import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue import org.jetbrains.jet.lang.resolve.scopes.receivers.Qualifier -import org.jetbrains.jet.plugin.util.ProjectRootsUtil import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.noSubstitutions import org.jetbrains.jet.lang.resolve.DescriptorUtils import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils +import com.intellij.codeInsight.intention.IntentionAction +import org.jetbrains.jet.lang.psi.JetSimpleNameExpression +import com.intellij.codeInsight.daemon.quickFix.CreateClassOrPackageFix +import org.jetbrains.jet.plugin.quickfix.DelegatingIntentionAction +import org.jetbrains.jet.plugin.JetBundle import com.intellij.psi.PsiPackage -import org.jetbrains.jet.plugin.quickfix.createFromUsage.createClass.canRefactor import com.intellij.psi.PsiDirectory +import org.jetbrains.jet.lang.psi.JetElement +import org.jetbrains.jet.plugin.util.ProjectRootsUtil private fun String.checkClassName(): Boolean = isNotEmpty() && Character.isUpperCase(first()) +private fun String.checkPackageName(): Boolean = isNotEmpty() && Character.isLowerCase(first()) + private fun getTargetParentByQualifier( file: JetFile, isQualified: Boolean, @@ -99,4 +104,26 @@ private fun PsiElement.canRefactor(): Boolean { else -> false } +} + +private fun JetSimpleNameExpression.getCreatePackageFixIfApplicable(targetParent: PsiElement): IntentionAction? { + val name = getReferencedName() + if (!name.checkPackageName()) return null + + val basePackage: PsiPackage = when (targetParent) { + is JetFile -> JavaPsiFacade.getInstance(targetParent.getProject()).findPackage(targetParent.getPackageFqName().asString()) + is PsiPackage -> targetParent : PsiPackage + else -> null + } ?: return null + + val baseName = basePackage.getQualifiedName() + val fullName = if (baseName.isNotEmpty()) "$baseName.$name" else name + + val javaFix = CreateClassOrPackageFix.createFix(fullName, getResolveScope(), this, basePackage, null, null, null) ?: return null + + return object: DelegatingIntentionAction(javaFix) { + override fun getFamilyName(): String = JetBundle.message("create.from.usage.family") + + override fun getText(): String = JetBundle.message("create.0.from.usage", "package '${fullName}'") + } } \ No newline at end of file