Refactored reference shortening utility (added expression references shortening and rewritten to Kotlin)

This commit is contained in:
Valentin Kipyatkov
2013-12-25 18:40:16 +04:00
parent fa8127d1a0
commit b71020efc5
68 changed files with 646 additions and 133 deletions
@@ -2,6 +2,12 @@
<item name='com.intellij.psi.PsiDocumentManager com.intellij.psi.PsiDocumentManager getInstance(com.intellij.openapi.project.Project)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiElement com.intellij.psi.PsiElement copy()'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiElement com.intellij.psi.PsiElement replace(com.intellij.psi.PsiElement)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.psi.PsiReferenceService java.util.List&lt;com.intellij.psi.PsiReference&gt; getReferences(com.intellij.psi.PsiElement, com.intellij.psi.PsiReferenceService.Hints)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
@@ -37,6 +37,7 @@ public class JetTypeArgumentList extends JetElementImpl {
return visitor.visitTypeArgumentList(this, data);
}
@NotNull
public List<JetTypeProjection> getArguments() {
return findChildrenByType(JetNodeTypes.TYPE_PROJECTION);
}
@@ -82,7 +82,7 @@ public class KotlinLightMethodForDeclaration(manager: PsiManager, val method: Ps
override fun getParameterList(): PsiParameterList = paramsList.getValue()!!
override fun copy(): PsiElement? {
override fun copy(): PsiElement {
return KotlinLightMethodForDeclaration(getManager()!!, method, jetDeclaration.copy() as JetDeclaration, getContainingClass()!!)
}
}
@@ -81,6 +81,7 @@ import org.jetbrains.jet.generators.tests.generator.TestClassModel
import org.jetbrains.jet.j2k.test.AbstractJavaToKotlinConverterPluginTest
import org.jetbrains.jet.j2k.test.AbstractJavaToKotlinConverterBasicTest
import org.jetbrains.jet.plugin.conversion.copy.AbstractJavaToKotlinCopyPasteConversionTest
import org.jetbrains.jet.shortenRefs.AbstractShortenRefsTest
fun main(args: Array<String>) {
System.setProperty("java.awt.headless", "true")
@@ -419,6 +420,10 @@ fun main(args: Array<String>) {
testClass(javaClass<AbstractJavaToKotlinCopyPasteConversionTest>()) {
model("copyPaste/conversion", extension = "java")
}
testClass(javaClass<AbstractShortenRefsTest>()) {
model("shortenRefs")
}
}
testGroup("j2k/tests/test", "j2k/tests/testData") {
@@ -43,11 +43,10 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.plugin.JetBundle;
import org.jetbrains.jet.plugin.codeInsight.CodeInsightUtils;
import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil;
import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening;
import org.jetbrains.jet.plugin.codeInsight.ShortenReferences;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@@ -116,7 +115,7 @@ public class JetAddFunctionToClassifierAction implements QuestionAction {
PsiElement anchor = body.getRBrace();
JetNamedFunction insertedFunctionElement = (JetNamedFunction) body.addBefore(functionElement, anchor);
ReferenceToClassesShortening.compactReferenceToClasses(Collections.singletonList(insertedFunctionElement));
ShortenReferences.instance$.process(insertedFunctionElement);
}
});
}
@@ -33,7 +33,7 @@ import org.jetbrains.jet.lang.psi.JetNamedFunction;
import org.jetbrains.jet.lang.psi.JetPsiFactory;
import org.jetbrains.jet.plugin.JetBundle;
import org.jetbrains.jet.plugin.codeInsight.CodeInsightUtils;
import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening;
import org.jetbrains.jet.plugin.codeInsight.ShortenReferences;
import javax.swing.*;
import java.util.ArrayList;
@@ -150,7 +150,7 @@ public class JetChangeFunctionSignatureAction implements QuestionAction {
newElement = JetPsiFactory.createFunction(project, signatureString);
}
newElement = (JetNamedFunction) element.replace(newElement);
ReferenceToClassesShortening.compactReferenceToClasses(Collections.singletonList(newElement));
ShortenReferences.instance$.process(newElement);
}
});
}
@@ -101,7 +101,7 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns
elementsToCompact.add((JetElement) added);
}
ReferenceToClassesShortening.compactReferenceToClasses(elementsToCompact);
ShortenReferences.instance$.process(elementsToCompact);
}
@Nullable
@@ -1,100 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.codeInsight;
import com.intellij.psi.PsiDocumentManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
import org.jetbrains.jet.plugin.quickfix.ImportInsertHelper;
import java.util.List;
public class ReferenceToClassesShortening {
private ReferenceToClassesShortening() {
}
public static void compactReferenceToClasses(List<? extends JetElement> elementsToCompact) {
if (elementsToCompact.isEmpty()) {
return;
}
PsiDocumentManager.getInstance(elementsToCompact.get(0).getProject()).commitAllDocuments();
final JetFile file = (JetFile) elementsToCompact.get(0).getContainingFile();
final BindingContext bc = AnalyzerFacadeWithCache.analyzeFileWithCache(file).getBindingContext();
for (JetElement element : elementsToCompact) {
element.accept(new JetVisitorVoid() {
@Override
public void visitJetElement(@NotNull JetElement element) {
element.acceptChildren(this);
}
@Override
public void visitTypeReference(@NotNull JetTypeReference typeReference) {
super.visitTypeReference(typeReference);
JetTypeElement typeElement = typeReference.getTypeElement();
if (typeElement instanceof JetNullableType) {
typeElement = ((JetNullableType) typeElement).getInnerType();
}
if (typeElement instanceof JetUserType) {
JetUserType userType = (JetUserType) typeElement;
DeclarationDescriptor target = bc.get(BindingContext.REFERENCE_TARGET,
userType.getReferenceExpression());
if (target instanceof ClassDescriptor) {
ClassDescriptor targetClass = (ClassDescriptor) target;
ClassDescriptor targetTopLevelClass = ImportInsertHelper.getTopLevelClass(targetClass);
JetScope scope = bc.get(BindingContext.TYPE_RESOLUTION_SCOPE, typeReference);
ClassifierDescriptor classifier = scope.getClassifier(targetTopLevelClass.getName());
if (targetTopLevelClass == classifier) {
compactReferenceToClass(userType, targetClass);
}
else if (classifier == null) {
ImportInsertHelper.addImportDirectiveIfNeeded(DescriptorUtils.getFqNameSafe(targetTopLevelClass), file);
compactReferenceToClass(userType, targetClass);
}
else {
// leave FQ name
}
}
}
}
private void compactReferenceToClass(JetUserType userType, ClassDescriptor targetClass) {
String name = targetClass.getName().asString();
DeclarationDescriptor parent = targetClass.getContainingDeclaration();
while (parent instanceof ClassDescriptor) {
name = parent.getName() + "." + name;
parent = parent.getContainingDeclaration();
}
JetTypeArgumentList typeArgumentList = userType.getTypeArgumentList();
JetTypeElement typeElement = JetPsiFactory.createType(userType.getProject(),
name + (typeArgumentList == null ? "" : typeArgumentList.getText())).getTypeElement();
assert typeElement != null;
userType.replace(typeElement);
}
});
}
}
}
@@ -0,0 +1,196 @@
package org.jetbrains.jet.plugin.codeInsight
import com.intellij.psi.PsiElement;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
import org.jetbrains.jet.plugin.project.CancelableResolveSession;
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
public object ShortenReferences {
public fun process(element: JetElement) {
process(Collections.singleton(element))
}
public fun process(elements: Iterable<JetElement>) {
val first = elements.firstOrNull()
if (first == null) return
val visitor = Visitor(first.getContainingFile() as JetFile)
for (element in elements) {
element.accept(visitor)
}
}
private class Visitor(val file: JetFile) : JetVisitorVoid() {
private var modificationCount = file.getManager()!!.getModificationTracker().getModificationCount()
private val resolveSession : CancelableResolveSession = AnalyzerFacadeWithCache.getLazyResolveSessionForFile(file)
get(){
val currentModificationCount = file.getManager()!!.getModificationTracker().getModificationCount()
if (currentModificationCount != modificationCount) {
$resolveSession = AnalyzerFacadeWithCache.getLazyResolveSessionForFile(file)
modificationCount = currentModificationCount
}
return $resolveSession
}
override fun visitJetElement(element : JetElement) {
element.acceptChildren(this)
}
override fun visitUserType(userType: JetUserType) {
val resultElement = processType(userType)
resultElement.acceptChildren(this)
}
private fun processType(userType: JetUserType): PsiElement {
if (userType.getQualifier() == null) return userType
val bindingContext = resolveSession.resolveToElement(userType)
val target = bindingContext.get(BindingContext.REFERENCE_TARGET, userType.getReferenceExpression())
if (target == null) return userType
// references to nested classes should be shortened when visiting qualifier
if (target.getContainingDeclaration() is ClassDescriptor) return userType
val typeReference = PsiTreeUtil.getParentOfType(userType, javaClass<JetTypeReference>())!!
val scope = bindingContext.get(BindingContext.TYPE_RESOLUTION_SCOPE, typeReference)!!
val name = target.getName()
val targetByName = scope.getClassifier(name) ?: scope.getPackage(name)
if (target == targetByName) {
return shortenType(userType)
}
else if (targetByName == null) {
addImportIfNeeded(target)
return shortenType(userType)
}
else {
// leave FQ name
return userType
}
}
private fun shortenType(userType: JetUserType): JetUserType {
val referenceExpression = userType.getReferenceExpression()
if (referenceExpression == null) return userType
val typeArgumentList = userType.getTypeArgumentList()
val text = referenceExpression.getText() + (if (typeArgumentList != null) typeArgumentList.getText() else "")
val newUserType = JetPsiFactory.createType(userType.getProject(), text).getTypeElement() as JetUserType
return userType.replace(newUserType) as JetUserType
}
override fun visitDotQualifiedExpression(expression: JetDotQualifiedExpression) {
val resultElement = processDotQualifiedExpression(expression)
resultElement.acceptChildren(this)
}
private fun processDotQualifiedExpression(qualifiedExpression: JetDotQualifiedExpression): PsiElement {
val selectorExpression = qualifiedExpression.getSelectorExpression()
if (selectorExpression is JetCallExpression) {
val calleeExpression = selectorExpression.getCalleeExpression()
if (calleeExpression is JetReferenceExpression) {
val targetClass = instantiatedClass(calleeExpression)
if (targetClass != null) {
return shortenIfPossible(qualifiedExpression, targetClass)
}
}
}
else if (selectorExpression is JetReferenceExpression) {
val bindingContext = resolveSession.resolveToElement(selectorExpression)
val target = bindingContext.get(BindingContext.REFERENCE_TARGET, selectorExpression)
if (target is ClassDescriptor || target is PackageViewDescriptor) { //TODO: should we ever add imports to real packages?
return shortenIfPossible(qualifiedExpression, target)
}
}
return qualifiedExpression
}
private fun instantiatedClass(calleeExpression: JetReferenceExpression): ClassDescriptor? {
val bindingContext = resolveSession.resolveToElement(calleeExpression)
val target = bindingContext.get(BindingContext.REFERENCE_TARGET, calleeExpression)
if (target != null) {
if (target is ConstructorDescriptor) {
return target.getContainingDeclaration()
}
}
else {
val targets = bindingContext.get(BindingContext.AMBIGUOUS_REFERENCE_TARGET, calleeExpression)
if (targets != null && !targets.isEmpty()) {
var targetClass: ClassDescriptor? = null
for (descriptor in targets) {
if (descriptor is ConstructorDescriptor) {
val classDescriptor = descriptor.getContainingDeclaration().getOriginal() as ClassDescriptor
if (targetClass == null || targetClass == classDescriptor) {
targetClass = classDescriptor
continue
}
}
return null
}
return targetClass
}
}
return null
}
private fun shortenIfPossible(qualifiedExpression: JetDotQualifiedExpression, targetClassOrPackage: DeclarationDescriptor): PsiElement {
// references to nested classes should be shortened when visiting qualifier
if (targetClassOrPackage.getContainingDeclaration() is ClassDescriptor) return qualifiedExpression
var bindingContext = resolveSession.resolveToElement(qualifiedExpression)
val referenceExpression = referenceExpression(qualifiedExpression.getSelectorExpression()!!)
val resolveBefore = resolveState(referenceExpression, bindingContext)
val copy = qualifiedExpression.copy()
val selectorExpression = qualifiedExpression.getSelectorExpression()!!
val newExpression = qualifiedExpression.replace(selectorExpression) as JetExpression
val newReferenceExpression = referenceExpression(newExpression)
bindingContext = resolveSession.resolveToElement(newReferenceExpression)
val resolveAfter = resolveState(newReferenceExpression, bindingContext)
if (resolveAfter != null) {
if (resolveBefore == resolveAfter) return newExpression
return newExpression.replace(copy) // revert shortening
}
addImportIfNeeded(targetClassOrPackage)
return newExpression
}
private fun resolveState(referenceExpression: JetReferenceExpression, bindingContext: BindingContext): Any? {
val target = bindingContext.get(BindingContext.REFERENCE_TARGET, referenceExpression)
if (target != null) return DescriptorRenderer.TEXT.render(target.getOriginal())
val targets = bindingContext.get(BindingContext.AMBIGUOUS_REFERENCE_TARGET, referenceExpression)
if (targets != null) return HashSet(targets.map{DescriptorRenderer.TEXT.render(it!!)})
return null
}
//TODO: do we need this "IfNeeded" check?
private fun addImportIfNeeded(descriptor : DeclarationDescriptor) {
ImportInsertHelper.addImportDirectiveIfNeeded(DescriptorUtils.getFqNameSafe(descriptor), file)
}
}
private fun referenceExpression(selectorExpression: JetExpression) = if (selectorExpression is JetCallExpression)
selectorExpression.getCalleeExpression() as JetReferenceExpression
else
selectorExpression as JetReferenceExpression
}
//TODO: how about such function in stdlib?
fun <T: Any> Iterable<T>.firstOrNull() : T? {
val iterator = this.iterator()
return if (iterator.hasNext()) iterator.next() else null
}
@@ -30,7 +30,7 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.plugin.codeInsight.CodeInsightUtils;
import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening;
import org.jetbrains.jet.plugin.codeInsight.ShortenReferences;
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
import org.jetbrains.jet.renderer.DescriptorRenderer;
@@ -86,7 +86,7 @@ public class MoveDeclarationsOutHelper {
dummyFirstStatement.delete();
}
ReferenceToClassesShortening.compactReferenceToClasses(propertiesDeclarations);
ShortenReferences.instance$.process(propertiesDeclarations);
return PsiUtilCore.toPsiElementArray(resultStatements);
}
@@ -26,7 +26,7 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.plugin.JetBundle;
import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening;
import org.jetbrains.jet.plugin.codeInsight.ShortenReferences;
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
import org.jetbrains.jet.renderer.DescriptorRenderer;
@@ -47,7 +47,7 @@ public class ReconstructTypeInCastOrIsAction extends PsiElementBaseIntentionActi
JetType type = getReconstructedType(typeRef);
JetTypeReference newType = JetPsiFactory.createType(project, DescriptorRenderer.SOURCE_CODE.renderType(type));
JetTypeReference replaced = (JetTypeReference) typeRef.replace(newType);
ReferenceToClassesShortening.compactReferenceToClasses(Collections.singletonList(replaced));
ShortenReferences.instance$.process(replaced);
}
@Override
@@ -45,7 +45,7 @@ import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.plugin.JetBundle;
import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening;
import org.jetbrains.jet.plugin.codeInsight.ShortenReferences;
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
import org.jetbrains.jet.renderer.DescriptorRenderer;
@@ -257,7 +257,7 @@ public class SpecifyTypeExplicitlyAction extends PsiElementBaseIntentionAction {
manager.startTemplate(editor, builder.buildInlineTemplate(), new TemplateEditingAdapter() {
@Override
public void templateFinished(Template template, boolean brokenOff) {
ReferenceToClassesShortening.compactReferenceToClasses(Collections.singletonList(namedDeclaration));
ShortenReferences.instance$.process(getTypeRef(namedDeclaration));
}
});
}
@@ -28,7 +28,7 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening;
import org.jetbrains.jet.plugin.codeInsight.ShortenReferences;
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
import org.jetbrains.jet.plugin.util.JetPsiMatcher;
import org.jetbrains.jet.renderer.DescriptorRenderer;
@@ -128,7 +128,7 @@ public class DeclarationUtils {
);
if (inferredType != null) {
ReferenceToClassesShortening.compactReferenceToClasses(Collections.singletonList(property.getTypeRef()));
ShortenReferences.instance$.process(property.getTypeRef());
}
return newInitializer;
@@ -85,6 +85,7 @@ public final class AnalyzerFacadeWithCache {
return cancelableResolveSession.resolveToElement(jetElement);
}
@NotNull
public static CancelableResolveSession getLazyResolveSessionForFile(@NotNull JetFile file) {
Project project = file.getProject();
DeclarationsCacheProvider provider = KotlinCacheManager.getInstance(project).getRegisteredProvider(TargetPlatformDetector.getPlatform(file));
@@ -64,7 +64,7 @@ import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.plugin.JetBundle;
import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil;
import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening;
import org.jetbrains.jet.plugin.codeInsight.ShortenReferences;
import org.jetbrains.jet.plugin.presentation.JetClassPresenter;
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
import org.jetbrains.jet.plugin.refactoring.JetNameSuggester;
@@ -801,7 +801,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase {
}
});
ReferenceToClassesShortening.compactReferenceToClasses(typeRefsToShorten);
ShortenReferences.instance$.process(typeRefsToShorten);
}
});
}
@@ -170,15 +170,4 @@ public class ImportInsertHelper {
return true;
}
public static ClassDescriptor getTopLevelClass(ClassDescriptor classDescriptor) {
while (true) {
DeclarationDescriptor parent = classDescriptor.getContainingDeclaration();
if (parent instanceof ClassDescriptor) {
classDescriptor = (ClassDescriptor) parent;
} else {
return classDescriptor;
}
}
}
}
@@ -59,7 +59,7 @@ import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.plugin.JetLanguage;
import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening;
import org.jetbrains.jet.plugin.codeInsight.ShortenReferences;
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
import org.jetbrains.jet.plugin.project.CancelableResolveSession;
import org.jetbrains.jet.renderer.DescriptorRenderer;
@@ -292,7 +292,7 @@ public class KotlinInlineValHandler extends InlineActionHandler {
functionLiteral.addAfter(whitespaceToAdd, openBraceElement);
}
}
ReferenceToClassesShortening.compactReferenceToClasses(functionLiteralExpression.getValueParameters());
ShortenReferences.instance$.process(functionLiteralExpression.getValueParameters());
}
}
@@ -332,7 +332,7 @@ public class KotlinInlineValHandler extends InlineActionHandler {
for (JetCallExpression call : callsToAddArguments) {
call.addAfter(JetPsiFactory.createTypeArguments(containingFile.getProject(), "<" + typeArguments + ">"),
call.getCalleeExpression());
ReferenceToClassesShortening.compactReferenceToClasses(Arrays.asList(call.getTypeArgumentList()));
ShortenReferences.instance$.process(call.getTypeArgumentList());
}
}
@@ -49,7 +49,7 @@ import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.plugin.codeInsight.CodeInsightUtils;
import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening;
import org.jetbrains.jet.plugin.codeInsight.ShortenReferences;
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
import org.jetbrains.jet.plugin.refactoring.*;
import org.jetbrains.jet.renderer.DescriptorRenderer;
@@ -388,7 +388,7 @@ public class JetIntroduceVariableHandler extends JetIntroduceHandlerBase {
}
propertyRef.set(property);
if (noTypeInference) {
ReferenceToClassesShortening.compactReferenceToClasses(Collections.singletonList(property));
ShortenReferences.instance$.process(property);
}
}
};
@@ -0,0 +1 @@
val x = <selection>java.util.Collections.copy()</selection>
@@ -0,0 +1,3 @@
import java.util.Collections
val x = Collections.copy()
@@ -0,0 +1,3 @@
class A {
val x = <selection>java.io.File()</selection>
}
@@ -0,0 +1,5 @@
import java.io.File
class A {
val x = File()
}
@@ -0,0 +1,3 @@
class A {
val x = <selection>java.util.HashMap<java.util.ArrayList<java.io.File>, String>()</selection>
}
@@ -0,0 +1,7 @@
import java.util.HashMap
import java.util.ArrayList
import java.io.File
class A {
val x = HashMap<ArrayList<File>, String>()
}
@@ -0,0 +1,3 @@
import java.util.Date
val x = <selection>java.sql.Date(1)</selection>
@@ -0,0 +1,4 @@
import java.util.Date
import java.sql
val x = sql.Date(1)
@@ -0,0 +1,5 @@
fun File(): String = ""
class A {
val x = <selection>java.io.File()</selection>
}
@@ -0,0 +1,5 @@
fun File(): String = ""
class A {
val x = java.io.File()
}
@@ -0,0 +1,5 @@
fun Random(): Int = 1
class A {
val x = <selection>java.util.Random()</selection>
}
@@ -0,0 +1,5 @@
fun Random(): Int = 1
class A {
val x = java.util.Random()
}
@@ -0,0 +1,4 @@
fun foo(){
val Random = {}
val x = <selection>java.util.Random()</selection>
}
@@ -0,0 +1,4 @@
fun foo(){
val Random = {}
val x = java.util.Random()
}
@@ -0,0 +1,6 @@
import java.util.Random
fun foo(){
val Random = 1
val x = Random()
}
@@ -0,0 +1,4 @@
fun foo(){
val Random = 1
val x = <selection>java.util.Random()</selection>
}
@@ -0,0 +1,6 @@
fun File(p: Int): String = ""
fun File(p: String): String = ""
class A {
val x = <selection>java.io.File()</selection>
}
@@ -0,0 +1,6 @@
fun File(p: Int): String = ""
fun File(p: String): String = ""
class A {
val x = java.io.File()
}
@@ -0,0 +1 @@
val x = <selection>java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock()</selection>
@@ -0,0 +1,3 @@
import java.util.concurrent.locks.ReentrantReadWriteLock
val x = ReentrantReadWriteLock.WriteLock()
@@ -0,0 +1,3 @@
import java.io.File
val f = <selection>java.io.File()</selection>
@@ -0,0 +1,3 @@
import java.io.File
val f = File()
@@ -0,0 +1,3 @@
package java.io
val f = <selection>java.io.File()</selection>
@@ -0,0 +1,3 @@
package java.io
val f = File()
@@ -0,0 +1,3 @@
import java.io.*
val f = <selection>java.io.File()</selection>
@@ -0,0 +1,3 @@
import java.io.*
val f = File()
@@ -0,0 +1,3 @@
class A {
var x: <selection>((java.io.File, java.util.ArrayList<String>) -> java.awt.Container)?</selection> = null
}
@@ -0,0 +1,7 @@
import java.io.File
import java.util.ArrayList
import java.awt.Container
class A {
var x: ((File, ArrayList<String>) -> Container)? = null
}
@@ -0,0 +1,3 @@
class A {
val x: <selection>java.util.HashMap<java.util.ArrayList<java.io.File>, String></selection>
}
@@ -0,0 +1,7 @@
import java.util.HashMap
import java.util.ArrayList
import java.io.File
class A {
val x: HashMap<ArrayList<File>, String>
}
@@ -0,0 +1,6 @@
import java.util.HashMap
import java.util.List
fun f(){
foo(<selection>java.util.HashMap<jet.String, java.util.List<jet.Int>>()</selection>)
}
@@ -0,0 +1,6 @@
import java.util.HashMap
import java.util.List
fun f(){
foo(HashMap<String, List<Int>>())
}
@@ -0,0 +1,3 @@
import java.util.Date
class A : <selection>java.sql.Date</selection>
@@ -0,0 +1,4 @@
import java.util.Date
import java.sql
class A : sql.Date
@@ -0,0 +1 @@
class A : <selection>java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock</selection>
@@ -0,0 +1,3 @@
import java.util.concurrent.locks.ReentrantReadWriteLock
class A : ReentrantReadWriteLock.WriteLock
@@ -0,0 +1,3 @@
import java.io.File
class A : <selection>java.io.File</selection>
@@ -0,0 +1,3 @@
import java.io.File
class A : File
@@ -0,0 +1,3 @@
package java.io
class A : <selection>java.io.File</selection>
@@ -0,0 +1,3 @@
package java.io
class A : File
@@ -0,0 +1,3 @@
class A {
val x: <selection>java.io.File?</selection>
}
@@ -0,0 +1,5 @@
import java.io.File
class A {
val x: File?
}
@@ -0,0 +1,3 @@
class A {
val x: <selection>java.util.ArrayList<java.util.ArrayList<java.io.File>></selection>
}
@@ -0,0 +1,6 @@
import java.util.ArrayList
import java.io.File
class A {
val x: ArrayList<ArrayList<File>>
}
@@ -0,0 +1 @@
class A : <selection>java.io.File</selection>
@@ -0,0 +1,3 @@
import java.io.File
class A : File
@@ -0,0 +1,3 @@
class A {
val x: <selection>java.util.HashMap<java.util.Date, java.sql.Date></selection>
}
@@ -0,0 +1,7 @@
import java.util.HashMap
import java.util.Date
import java.sql
class A {
val x: HashMap<Date, sql.Date>
}
@@ -0,0 +1,51 @@
package org.jetbrains.jet.shortenRefs
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import org.jetbrains.jet.InTextDirectivesUtils
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
import org.jetbrains.jet.lang.psi.JetExpression
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
import org.jetbrains.jet.lang.psi.JetFile
import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils
import org.jetbrains.jet.lang.resolve.name.FqName
import org.jetbrains.jet.plugin.project.TargetPlatform
import org.jetbrains.jet.plugin.JetWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.jet.lang.resolve.name.Name
import com.intellij.util.containers.Predicate
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
import com.intellij.openapi.application.Application
import com.intellij.openapi.application.ApplicationManager
import org.jetbrains.jet.plugin.PluginTestCaseBase
import java.io.File
import com.intellij.openapi.command.CommandProcessor
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.jet.lang.psi.JetReferenceExpression
import com.intellij.psi.PsiElement
import org.jetbrains.jet.plugin.codeInsight.ShortenReferences
import org.jetbrains.jet.lang.psi.JetElement
import org.jetbrains.jet.JetTestCaseBuilder
abstract class AbstractShortenRefsTest : LightCodeInsightFixtureTestCase() {
override fun getTestDataPath() = JetTestCaseBuilder.getHomeDirectory()
override fun getProjectDescriptor() = JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
protected fun doTest(testPath: String) {
val fixture = myFixture!!
fixture.configureByFile(testPath)
val file = fixture.getFile() as JetFile
val selectionModel = fixture.getEditor()!!.getSelectionModel()
if (!selectionModel.hasSelection()) error("No selection in input file")
val element = PsiTreeUtil.findElementOfClassAtRange(file, selectionModel.getSelectionStart(), selectionModel.getSelectionEnd(), javaClass<JetElement>())!!
CommandProcessor.getInstance()!!.executeCommand(getProject(), {
ApplicationManager.getApplication()!!.runWriteAction {
ShortenReferences.process(element)
}
}, null, null)
selectionModel.removeSelection()
fixture.checkResultByFile(testPath + ".after")
}
}
@@ -0,0 +1,178 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.shortenRefs;
import junit.framework.Assert;
import junit.framework.Test;
import junit.framework.TestSuite;
import java.io.File;
import java.util.regex.Pattern;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.test.InnerTestClasses;
import org.jetbrains.jet.test.TestMetadata;
import org.jetbrains.jet.shortenRefs.AbstractShortenRefsTest;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("idea/testData/shortenRefs")
@InnerTestClasses({ShortenRefsTestGenerated.Constructor.class, ShortenRefsTestGenerated.Type.class})
public class ShortenRefsTestGenerated extends AbstractShortenRefsTest {
public void testAllFilesPresentInShortenRefs() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/shortenRefs"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("JavaStaticMethod.kt")
public void testJavaStaticMethod() throws Exception {
doTest("idea/testData/shortenRefs/JavaStaticMethod.kt");
}
@TestMetadata("idea/testData/shortenRefs/constructor")
public static class Constructor extends AbstractShortenRefsTest {
public void testAllFilesPresentInConstructor() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/shortenRefs/constructor"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("Ambiguous.kt")
public void testAmbiguous() throws Exception {
doTest("idea/testData/shortenRefs/constructor/Ambiguous.kt");
}
@TestMetadata("GenericType.kt")
public void testGenericType() throws Exception {
doTest("idea/testData/shortenRefs/constructor/GenericType.kt");
}
@TestMetadata("LeaveQualified.kt")
public void testLeaveQualified() throws Exception {
doTest("idea/testData/shortenRefs/constructor/LeaveQualified.kt");
}
@TestMetadata("LeaveQualified1.kt")
public void testLeaveQualified1() throws Exception {
doTest("idea/testData/shortenRefs/constructor/LeaveQualified1.kt");
}
@TestMetadata("LeaveQualified2.kt")
public void testLeaveQualified2() throws Exception {
doTest("idea/testData/shortenRefs/constructor/LeaveQualified2.kt");
}
@TestMetadata("LeaveQualified3.kt")
public void testLeaveQualified3() throws Exception {
doTest("idea/testData/shortenRefs/constructor/LeaveQualified3.kt");
}
@TestMetadata("LeaveQualified5.kt")
public void testLeaveQualified5() throws Exception {
doTest("idea/testData/shortenRefs/constructor/LeaveQualified5.kt");
}
@TestMetadata("NestedClass.kt")
public void testNestedClass() throws Exception {
doTest("idea/testData/shortenRefs/constructor/NestedClass.kt");
}
@TestMetadata("NoImportNeeded.kt")
public void testNoImportNeeded() throws Exception {
doTest("idea/testData/shortenRefs/constructor/NoImportNeeded.kt");
}
@TestMetadata("NoImportNeeded2.kt")
public void testNoImportNeeded2() throws Exception {
doTest("idea/testData/shortenRefs/constructor/NoImportNeeded2.kt");
}
@TestMetadata("NoImportNeeded3.kt")
public void testNoImportNeeded3() throws Exception {
doTest("idea/testData/shortenRefs/constructor/NoImportNeeded3.kt");
}
}
@TestMetadata("idea/testData/shortenRefs/type")
public static class Type extends AbstractShortenRefsTest {
public void testAllFilesPresentInType() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/shortenRefs/type"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("FunctionType.kt")
public void testFunctionType() throws Exception {
doTest("idea/testData/shortenRefs/type/FunctionType.kt");
}
@TestMetadata("GenericType.kt")
public void testGenericType() throws Exception {
doTest("idea/testData/shortenRefs/type/GenericType.kt");
}
@TestMetadata("GenericType2.kt")
public void testGenericType2() throws Exception {
doTest("idea/testData/shortenRefs/type/GenericType2.kt");
}
@TestMetadata("LeaveQualified.kt")
public void testLeaveQualified() throws Exception {
doTest("idea/testData/shortenRefs/type/LeaveQualified.kt");
}
@TestMetadata("NestedClass.kt")
public void testNestedClass() throws Exception {
doTest("idea/testData/shortenRefs/type/NestedClass.kt");
}
@TestMetadata("NoImportNeeded.kt")
public void testNoImportNeeded() throws Exception {
doTest("idea/testData/shortenRefs/type/NoImportNeeded.kt");
}
@TestMetadata("NoImportNeeded2.kt")
public void testNoImportNeeded2() throws Exception {
doTest("idea/testData/shortenRefs/type/NoImportNeeded2.kt");
}
@TestMetadata("NullableType.kt")
public void testNullableType() throws Exception {
doTest("idea/testData/shortenRefs/type/NullableType.kt");
}
@TestMetadata("SameClassTwice.kt")
public void testSameClassTwice() throws Exception {
doTest("idea/testData/shortenRefs/type/SameClassTwice.kt");
}
@TestMetadata("SimpleAddImport.kt")
public void testSimpleAddImport() throws Exception {
doTest("idea/testData/shortenRefs/type/SimpleAddImport.kt");
}
@TestMetadata("TwoClassesSameNames.kt")
public void testTwoClassesSameNames() throws Exception {
doTest("idea/testData/shortenRefs/type/TwoClassesSameNames.kt");
}
}
public static Test suite() {
TestSuite suite = new TestSuite("ShortenRefsTestGenerated");
suite.addTestSuite(ShortenRefsTestGenerated.class);
suite.addTestSuite(Constructor.class);
suite.addTestSuite(Type.class);
return suite;
}
}