FqName class

for type safety, to easier distinguish between:

* short names
* qualified names
* jvm names (slash-separated)
* special names like <root>
* null values that mean "undefined" and "root ns" in different contexts
This commit is contained in:
Stepan Koltsov
2012-03-13 21:51:38 +04:00
parent 15078b1b70
commit 82d77560a2
41 changed files with 434 additions and 222 deletions
@@ -27,6 +27,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import jet.runtime.typeinfo.JetValueParameter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.kt.JetValueParameterAnnotation;
import org.jetbrains.jet.util.QualifiedNamesUtil;
@@ -127,15 +128,15 @@ class JetFromJavaDescriptorHelper {
}
@Nullable
static String getJetTopLevelDeclarationFQN(@NotNull PsiMethod method) {
static FqName getJetTopLevelDeclarationFQN(@NotNull PsiMethod method) {
PsiClass containingClass = method.getContainingClass();
if (containingClass != null) {
String classFQN = containingClass.getQualifiedName();
FqName classFQN = new FqName(containingClass.getQualifiedName());
if (classFQN != null) {
if (QualifiedNamesUtil.fqnToShortName(classFQN).equals(JvmAbi.PACKAGE_CLASS)) {
String classParentFQN = QualifiedNamesUtil.withoutLastSegment(classFQN);
FqName classParentFQN = QualifiedNamesUtil.withoutLastSegment(classFQN);
return QualifiedNamesUtil.combine(classParentFQN, method.getName());
}
}
@@ -38,6 +38,7 @@ 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.BindingTraceContext;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.ImportsResolver;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.JetType;
@@ -94,7 +95,7 @@ public class JetShortNamesCache extends PsiShortNamesCache {
List<PsiClass> result = new ArrayList<PsiClass>();
for (String fqName : JetFullClassNameIndex.getInstance().getAllKeys(project)) {
if (QualifiedNamesUtil.fqnToShortName(fqName).equals(name)) {
if (QualifiedNamesUtil.fqnToShortName(new FqName(fqName)).equals(name)) {
PsiClass psiClass = javaElementFinder.findClass(fqName, scope);
if (psiClass != null) {
result.add(psiClass);
@@ -131,11 +132,11 @@ public class JetShortNamesCache extends PsiShortNamesCache {
}
@NotNull
public Collection<String> getFQNamesByName(@NotNull final String name, @NotNull GlobalSearchScope scope) {
public Collection<FqName> getFQNamesByName(@NotNull final String name, @NotNull GlobalSearchScope scope) {
BindingContext context = getResolutionContext(scope);
return Collections2.filter(context.getKeys(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR), new Predicate<String>() {
return Collections2.filter(context.getKeys(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR), new Predicate<FqName>() {
@Override
public boolean apply(@Nullable String fqName) {
public boolean apply(@Nullable FqName fqName) {
return fqName != null && QualifiedNamesUtil.isShortNameForFQN(name, fqName);
}
});
@@ -174,7 +175,7 @@ public class JetShortNamesCache extends PsiShortNamesCache {
Collection<PsiMethod> topLevelFunctionPrototypes = JetFromJavaDescriptorHelper.getTopLevelFunctionPrototypesByName(name, project, scope);
for (PsiMethod method : topLevelFunctionPrototypes) {
String functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN(method);
FqName functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN(method);
if (functionFQN != null) {
JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, functionFQN);
Collection<? extends DeclarationDescriptor> declarationDescriptors = ImportsResolver.analyseImportReference(importDirective, jetScope, new BindingTraceContext());
@@ -246,7 +247,7 @@ public class JetShortNamesCache extends PsiShortNamesCache {
if (expressionType != null && scope != null) {
Collection<String> extensionFunctionsNames = getAllJetExtensionFunctionsNames(searchScope);
Set<String> functionFQNs = new java.util.HashSet<String>();
Set<FqName> functionFQNs = new java.util.HashSet<FqName>();
// Collect all possible extension function qualified names
for (String name : extensionFunctionsNames) {
@@ -258,7 +259,7 @@ public class JetShortNamesCache extends PsiShortNamesCache {
functionFQNs.add(JetPsiUtil.getFQName((JetNamedFunction) extensionFunction));
}
else if (extensionFunction instanceof PsiMethod) {
String functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN((PsiMethod) extensionFunction);
FqName functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN((PsiMethod) extensionFunction);
if (functionFQN != null) {
functionFQNs.add(functionFQN);
}
@@ -268,7 +269,7 @@ public class JetShortNamesCache extends PsiShortNamesCache {
}
// Iterate through the function with attempt to resolve found functions
for (String functionFQN : functionFQNs) {
for (FqName functionFQN : functionFQNs) {
for (CallableDescriptor functionDescriptor : ExpressionTypingUtils.canFindSuitableCall(
functionFQN, project, receiverExpression, expressionType, scope)) {
@@ -31,8 +31,10 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetImportDirective;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.plugin.completion.JetLookupObject;
import org.jetbrains.jet.plugin.quickfix.ImportClassHelper;
@@ -120,9 +122,7 @@ public class JetFunctionInsertHandler implements InsertHandler<LookupElement> {
if (descriptor instanceof SimpleFunctionDescriptor) {
final JetFile file = (JetFile) context.getFile();
SimpleFunctionDescriptor functionDescriptor = (SimpleFunctionDescriptor) descriptor;
final String fqn = DescriptorUtils.getFQName(functionDescriptor);
final SimpleFunctionDescriptor functionDescriptor = (SimpleFunctionDescriptor) descriptor;
// Don't insert import for qualified expression if don't try to insert extension function
if (PsiTreeUtil.getParentOfType(element, JetQualifiedExpression.class) != null &&
!functionDescriptor.getReceiverParameter().exists()) {
@@ -134,7 +134,8 @@ public class JetFunctionInsertHandler implements InsertHandler<LookupElement> {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
ImportClassHelper.addImportDirective(fqn, file);
final FqName fqn = DescriptorUtils.getFQName(functionDescriptor);
ImportClassHelper.addImportDirective(fqn.getFqName(), file);
}
});
}
@@ -45,6 +45,7 @@ import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.plugin.JetFileType;
import org.jetbrains.jet.plugin.actions.JetAddImportAction;
import org.jetbrains.jet.plugin.caches.JetCacheManager;
@@ -60,14 +61,14 @@ import java.util.*;
public class ImportClassAndFunFix extends JetHintAction<JetSimpleNameExpression> implements HighPriorityAction {
@NotNull
private final List<String> suggestions;
private final List<FqName> suggestions;
public ImportClassAndFunFix(@NotNull JetSimpleNameExpression element) {
super(element);
suggestions = computeSuggestions(element);
}
private static List<String> computeSuggestions(@NotNull JetSimpleNameExpression element) {
private static List<FqName> computeSuggestions(@NotNull JetSimpleNameExpression element) {
final PsiFile file = element.getContainingFile();
if (!(file instanceof JetFile)) {
return Collections.emptyList();
@@ -81,7 +82,7 @@ public class ImportClassAndFunFix extends JetHintAction<JetSimpleNameExpression>
assert referenceName != null;
final ArrayList<String> result = new ArrayList<String>();
final ArrayList<FqName> result = Lists.newArrayList();
result.addAll(getClassNames(referenceName, file.getProject()));
result.addAll(getJetTopLevelFunctions(referenceName, element, file.getProject()));
result.addAll(getJetExtensionFunctions(referenceName, element, file.getProject()));
@@ -89,23 +90,23 @@ public class ImportClassAndFunFix extends JetHintAction<JetSimpleNameExpression>
return result;
}
private static Collection<String> getJetTopLevelFunctions(@NotNull String referenceName, JetSimpleNameExpression expression, @NotNull Project project) {
private static Collection<FqName> getJetTopLevelFunctions(@NotNull String referenceName, JetSimpleNameExpression expression, @NotNull Project project) {
JetShortNamesCache namesCache = JetCacheManager.getInstance(project).getNamesCache();
Collection<FunctionDescriptor> topLevelFunctions = namesCache.getTopLevelFunctionDescriptorsByName(
referenceName,
expression,
GlobalSearchScope.allScope(project));
return Collections2.transform(topLevelFunctions, new Function<DeclarationDescriptor, String>() {
return Collections2.transform(topLevelFunctions, new Function<DeclarationDescriptor, FqName>() {
@Override
public String apply(@Nullable DeclarationDescriptor declarationDescriptor) {
public FqName apply(@Nullable DeclarationDescriptor declarationDescriptor) {
assert declarationDescriptor != null;
return DescriptorUtils.getFQName(declarationDescriptor);
}
});
}
private static Collection<String> getJetExtensionFunctions(
private static Collection<FqName> getJetExtensionFunctions(
@NotNull final String referenceName,
@NotNull JetSimpleNameExpression expression,
@NotNull Project project
@@ -121,9 +122,9 @@ public class ImportClassAndFunFix extends JetHintAction<JetSimpleNameExpression>
expression,
GlobalSearchScope.allScope(project));
return Collections2.transform(jetCallableExtensions, new Function<DeclarationDescriptor, String>() {
return Collections2.transform(jetCallableExtensions, new Function<DeclarationDescriptor, FqName>() {
@Override
public String apply(@Nullable DeclarationDescriptor declarationDescriptor) {
public FqName apply(@Nullable DeclarationDescriptor declarationDescriptor) {
assert declarationDescriptor != null;
return DescriptorUtils.getFQName(declarationDescriptor);
}
@@ -133,9 +134,9 @@ public class ImportClassAndFunFix extends JetHintAction<JetSimpleNameExpression>
/*
* Searches for possible class names in kotlin context and java facade.
*/
public static List<String> getClassNames(@NotNull String referenceName, @NotNull Project project) {
public static ArrayList<FqName> getClassNames(@NotNull String referenceName, @NotNull Project project) {
final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
Set<String> possibleResolveNames = Sets.newHashSet();
Set<FqName> possibleResolveNames = Sets.newHashSet();
possibleResolveNames.addAll(JetCacheManager.getInstance(project).getNamesCache().getFQNamesByName(referenceName, scope));
possibleResolveNames.addAll(getJavaClasses(referenceName, project, scope));
@@ -143,7 +144,7 @@ public class ImportClassAndFunFix extends JetHintAction<JetSimpleNameExpression>
return Lists.newArrayList(possibleResolveNames);
}
private static Collection<String> getJavaClasses(@NotNull final String typeName, @NotNull Project project, final GlobalSearchScope scope) {
private static Collection<FqName> getJavaClasses(@NotNull final String typeName, @NotNull Project project, final GlobalSearchScope scope) {
PsiShortNamesCache cache = PsiShortNamesCache.getInstance(project);
PsiClass[] classes = cache.getClassesByName(typeName, new DelegatingGlobalSearchScope(scope) {
@@ -153,12 +154,12 @@ public class ImportClassAndFunFix extends JetHintAction<JetSimpleNameExpression>
}
});
return Collections2.transform(Lists.newArrayList(classes), new Function<PsiClass, String>() {
return Collections2.transform(Lists.newArrayList(classes), new Function<PsiClass, FqName>() {
@Nullable
@Override
public String apply(@Nullable PsiClass javaClass) {
public FqName apply(@Nullable PsiClass javaClass) {
assert javaClass != null;
return javaClass.getQualifiedName();
return new FqName(javaClass.getQualifiedName());
}
});
}
@@ -179,7 +180,7 @@ public class ImportClassAndFunFix extends JetHintAction<JetSimpleNameExpression>
}
if (!ApplicationManager.getApplication().isUnitTestMode()) {
String hintText = ShowAutoImportPass.getMessage(suggestions.size() > 1, suggestions.get(0));
String hintText = ShowAutoImportPass.getMessage(suggestions.size() > 1, suggestions.get(0).getFqName());
HintManager.getInstance().showQuestionHint(
editor, hintText,
@@ -224,7 +225,13 @@ public class ImportClassAndFunFix extends JetHintAction<JetSimpleNameExpression>
@NotNull
private JetAddImportAction createAction(@NotNull Project project, @NotNull Editor editor) {
return new JetAddImportAction(project, editor, element, suggestions);
Collection<String> suggesionStrings = Collections2.transform(suggestions, new Function<FqName, String>() {
@Override
public String apply(FqName fqName) {
return fqName.getFqName();
}
});
return new JetAddImportAction(project, editor, element, suggesionStrings);
}
@Nullable
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.DefaultModuleConfiguration;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
import org.jetbrains.jet.lang.resolve.java.JavaBridgeConfiguration;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
@@ -101,9 +102,9 @@ public class ImportClassHelper {
}
// Check that import is useless
private static boolean isImportedByDefault(@NotNull String importString, @NotNull String filePackageFqn) {
private static boolean isImportedByDefault(@NotNull String importString, @NotNull FqName filePackageFqn) {
if (QualifiedNamesUtil.isOneSegmentFQN(importString) ||
filePackageFqn.equals(QualifiedNamesUtil.withoutLastSegment(importString))) {
filePackageFqn.getFqName().equals(QualifiedNamesUtil.withoutLastSegment(importString))) {
return true;
}
@@ -31,6 +31,7 @@ import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.FqName;
import java.util.Arrays;
import java.util.Collection;
@@ -41,7 +42,7 @@ import java.util.Map;
* @author yole
*/
public class JetRunConfiguration extends ModuleBasedConfiguration<RunConfigurationModule> implements CommonJavaRunConfigurationParameters {
public String MAIN_CLASS_NAME;
public FqName MAIN_CLASS_NAME;
public String VM_PARAMETERS;
public String PROGRAM_PARAMETERS;
public String WORKING_DIRECTORY;
@@ -132,7 +133,7 @@ public class JetRunConfiguration extends ModuleBasedConfiguration<RunConfigurati
@Override
public String getRunClass() {
return MAIN_CLASS_NAME;
return MAIN_CLASS_NAME.getFqName();
}
@Override
@@ -178,14 +179,14 @@ public class JetRunConfiguration extends ModuleBasedConfiguration<RunConfigurati
final RunConfigurationModule module = myConfiguration.getConfigurationModule();
final int classPathType = JavaParametersUtil.getClasspathType(module,
myConfiguration.MAIN_CLASS_NAME,
myConfiguration.MAIN_CLASS_NAME.getFqName(),
false);
final String jreHome = myConfiguration.ALTERNATIVE_JRE_PATH_ENABLED ? myConfiguration.ALTERNATIVE_JRE_PATH
: null;
JavaParametersUtil.configureModule(module, params, classPathType, jreHome);
JavaParametersUtil.configureConfiguration(params, myConfiguration);
params.setMainClass(myConfiguration.MAIN_CLASS_NAME);
params.setMainClass(myConfiguration.MAIN_CLASS_NAME.getFqName());
return params;
}
@@ -23,6 +23,7 @@ import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.LabeledComponent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.FqName;
import javax.swing.*;
import java.awt.*;
@@ -54,7 +55,7 @@ public class JetRunConfigurationEditor extends SettingsEditor<JetRunConfiguratio
@Override
protected void resetEditorFrom(JetRunConfiguration configuration) {
myCommonProgramParameters.reset(configuration);
myMainClassField.setText(configuration.MAIN_CLASS_NAME);
myMainClassField.setText(configuration.MAIN_CLASS_NAME.getFqName());
myModuleSelector.reset(configuration);
}
@@ -62,7 +63,7 @@ public class JetRunConfigurationEditor extends SettingsEditor<JetRunConfiguratio
protected void applyEditorTo(JetRunConfiguration configuration) throws ConfigurationException {
myModuleSelector.applyTo(configuration);
myCommonProgramParameters.applyTo(configuration);
configuration.MAIN_CLASS_NAME = myMainClassField.getText();
configuration.MAIN_CLASS_NAME = new FqName(myMainClassField.getText());
}
@NotNull
@@ -28,6 +28,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.plugin.JetMainDetector;
@@ -60,8 +61,8 @@ public class JetRunConfigurationProducer extends RuntimeConfigurationProducer im
JetFile jetFile = (JetFile) psiFile;
if (JetMainDetector.hasMain(jetFile.getDeclarations())) {
mySourceElement = jetFile;
String fqName = JetPsiUtil.getFQName(jetFile);
String className = fqName.length() == 0 ? JvmAbi.PACKAGE_CLASS : fqName + "." + JvmAbi.PACKAGE_CLASS;
FqName fqName = JetPsiUtil.getFQName(jetFile);
FqName className = fqName.child(JvmAbi.PACKAGE_CLASS);
return createConfigurationByQName(module, configurationContext, className);
}
}
@@ -71,12 +72,12 @@ public class JetRunConfigurationProducer extends RuntimeConfigurationProducer im
private RunnerAndConfigurationSettings createConfigurationByQName(
@NotNull Module module,
ConfigurationContext context,
@NotNull String fqName
@NotNull FqName fqName
) {
RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(module.getProject(), context);
JetRunConfiguration configuration = (JetRunConfiguration) settings.getConfiguration();
configuration.setModule(module);
configuration.setName(StringUtil.trimEnd(fqName, "." + JvmAbi.PACKAGE_CLASS));
configuration.setName(StringUtil.trimEnd(fqName.getFqName(), "." + JvmAbi.PACKAGE_CLASS));
configuration.MAIN_CLASS_NAME = fqName;
return settings;
}
@@ -28,6 +28,7 @@ import com.intellij.refactoring.rename.RenameProcessor;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.plugin.PluginTestCaseBase;
import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade;
@@ -54,10 +55,10 @@ public class RenameInKotlinTest extends MultiFileTestCase {
}
public void testRenameKotlinClass() throws Exception {
doTestWithRenameClass("testing.rename.First", "Third");
doTestWithRenameClass(new FqName("testing.rename.First"), "Third");
}
private void doTestWithRenameClass(@NonNls final String qClassName, @NonNls final String newName) throws Exception {
private void doTestWithRenameClass(@NonNls final FqName qClassName, @NonNls final String newName) throws Exception {
doTest(new PerformAction() {
@Override
public void performAction(VirtualFile rootDir, VirtualFile rootAfter) throws Exception {