Only normalize names when accessing PSI, not earlier

#KT-4833 Fixed
This commit is contained in:
Andrey Breslav
2014-06-10 11:34:54 +04:00
parent ef7b43ecdc
commit bb581bb645
14 changed files with 130 additions and 51 deletions
@@ -48,16 +48,7 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import static org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils.safeNameForLazyResolve;
public class ResolveSession implements KotlinCodeAnalyzer { public class ResolveSession implements KotlinCodeAnalyzer {
private static final Function<FqName, Name> NO_ALIASES = new Function<FqName, Name>() {
@Override
public Name fun(FqName name) {
return null;
}
};
private final LazyResolveStorageManager storageManager; private final LazyResolveStorageManager storageManager;
private final ExceptionTracker exceptionTracker; private final ExceptionTracker exceptionTracker;
@@ -66,8 +57,6 @@ public class ResolveSession implements KotlinCodeAnalyzer {
private final BindingTrace trace; private final BindingTrace trace;
private final DeclarationProviderFactory declarationProviderFactory; private final DeclarationProviderFactory declarationProviderFactory;
private final Function<FqName, Name> classifierAliases;
private final MemoizedFunctionToNullable<FqName, LazyPackageDescriptor> packages; private final MemoizedFunctionToNullable<FqName, LazyPackageDescriptor> packages;
private final PackageFragmentProvider packageFragmentProvider; private final PackageFragmentProvider packageFragmentProvider;
@@ -132,8 +121,6 @@ public class ResolveSession implements KotlinCodeAnalyzer {
this.trace = lockBasedLazyResolveStorageManager.createSafeTrace(delegationTrace); this.trace = lockBasedLazyResolveStorageManager.createSafeTrace(delegationTrace);
this.module = rootDescriptor; this.module = rootDescriptor;
this.classifierAliases = NO_ALIASES;
this.packages = storageManager.createMemoizedFunctionWithNullableValues(new MemoizedFunctionToNullable<FqName, LazyPackageDescriptor>() { this.packages = storageManager.createMemoizedFunctionWithNullableValues(new MemoizedFunctionToNullable<FqName, LazyPackageDescriptor>() {
@Nullable @Nullable
@Override @Override
@@ -257,7 +244,7 @@ public class ResolveSession implements KotlinCodeAnalyzer {
} }
} }
JetScope resolutionScope = getScopeProvider().getResolutionScopeForDeclaration(classOrObject); JetScope resolutionScope = getScopeProvider().getResolutionScopeForDeclaration(classOrObject);
Name name = safeNameForLazyResolve(classOrObject.getNameAsName()); Name name = classOrObject.getNameAsSafeName();
// Why not use the result here. Because it may be that there is a redeclaration: // Why not use the result here. Because it may be that there is a redeclaration:
// class A {} class A { fun foo(): A<completion here>} // class A {} class A { fun foo(): A<completion here>}
@@ -376,7 +363,7 @@ public class ResolveSession implements KotlinCodeAnalyzer {
throw new IllegalStateException("Unknown owner kind for a type parameter: " + ownerDescriptor); throw new IllegalStateException("Unknown owner kind for a type parameter: " + ownerDescriptor);
} }
Name name = ResolveSessionUtils.safeNameForLazyResolve(parameter.getNameAsName()); Name name = parameter.getNameAsSafeName();
for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) { for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
if (typeParameterDescriptor.getName().equals(name)) { if (typeParameterDescriptor.getName().equals(name)) {
return typeParameterDescriptor; return typeParameterDescriptor;
@@ -389,7 +376,7 @@ public class ResolveSession implements KotlinCodeAnalyzer {
@Override @Override
public DeclarationDescriptor visitNamedFunction(@NotNull JetNamedFunction function, Void data) { public DeclarationDescriptor visitNamedFunction(@NotNull JetNamedFunction function, Void data) {
JetScope scopeForDeclaration = getScopeProvider().getResolutionScopeForDeclaration(function); JetScope scopeForDeclaration = getScopeProvider().getResolutionScopeForDeclaration(function);
scopeForDeclaration.getFunctions(safeNameForLazyResolve(function)); scopeForDeclaration.getFunctions(function.getNameAsSafeName());
return getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, function); return getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, function);
} }
@@ -401,7 +388,7 @@ public class ResolveSession implements KotlinCodeAnalyzer {
// This is a primary constructor parameter // This is a primary constructor parameter
ClassDescriptor classDescriptor = getClassDescriptor(jetClass); ClassDescriptor classDescriptor = getClassDescriptor(jetClass);
if (parameter.hasValOrVarNode()) { if (parameter.hasValOrVarNode()) {
classDescriptor.getDefaultType().getMemberScope().getProperties(safeNameForLazyResolve(parameter)); classDescriptor.getDefaultType().getMemberScope().getProperties(parameter.getNameAsSafeName());
return getBindingContext().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter); return getBindingContext().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter);
} }
else { else {
@@ -417,7 +404,7 @@ public class ResolveSession implements KotlinCodeAnalyzer {
@Override @Override
public DeclarationDescriptor visitProperty(@NotNull JetProperty property, Void data) { public DeclarationDescriptor visitProperty(@NotNull JetProperty property, Void data) {
JetScope scopeForDeclaration = getScopeProvider().getResolutionScopeForDeclaration(property); JetScope scopeForDeclaration = getScopeProvider().getResolutionScopeForDeclaration(property);
scopeForDeclaration.getProperties(safeNameForLazyResolve(property)); scopeForDeclaration.getProperties(property.getNameAsSafeName());
return getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, property); return getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, property);
} }
@@ -434,16 +421,6 @@ public class ResolveSession implements KotlinCodeAnalyzer {
return result; return result;
} }
@NotNull
public Name resolveClassifierAlias(@NotNull FqName packageName, @NotNull Name alias) {
// TODO: creating a new FqName object every time...
Name actualName = classifierAliases.fun(packageName.child(alias));
if (actualName == null) {
return alias;
}
return actualName;
}
@NotNull @NotNull
private List<LazyPackageDescriptor> getAllPackages() { private List<LazyPackageDescriptor> getAllPackages() {
LazyPackageDescriptor rootPackage = getPackageFragment(FqName.ROOT); LazyPackageDescriptor rootPackage = getPackageFragment(FqName.ROOT);
@@ -148,7 +148,7 @@ public class ResolveSessionUtils {
@NotNull @NotNull
public static Name safeNameForLazyResolve(@Nullable Name name) { public static Name safeNameForLazyResolve(@Nullable Name name) {
return name != null ? name : NO_NAME_FOR_LAZY_RESOLVE; return name != null && !name.isSpecial() ? name : NO_NAME_FOR_LAZY_RESOLVE;
} }
@Nullable @Nullable
@@ -23,6 +23,7 @@ import com.google.common.collect.Multimap;
import kotlin.Function0; import kotlin.Function0;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils;
import org.jetbrains.jet.lang.resolve.lazy.data.JetClassInfoUtil; import org.jetbrains.jet.lang.resolve.lazy.data.JetClassInfoUtil;
import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo; import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo;
import org.jetbrains.jet.lang.resolve.lazy.data.JetScriptInfo; import org.jetbrains.jet.lang.resolve.lazy.data.JetScriptInfo;
@@ -107,18 +108,18 @@ public abstract class AbstractPsiBasedDeclarationProvider implements Declaration
@NotNull @NotNull
@Override @Override
public List<JetNamedFunction> getFunctionDeclarations(@NotNull Name name) { public List<JetNamedFunction> getFunctionDeclarations(@NotNull Name name) {
return Lists.newArrayList(index.invoke().functions.get(name)); return Lists.newArrayList(index.invoke().functions.get(ResolveSessionUtils.safeNameForLazyResolve(name)));
} }
@NotNull @NotNull
@Override @Override
public List<JetProperty> getPropertyDeclarations(@NotNull Name name) { public List<JetProperty> getPropertyDeclarations(@NotNull Name name) {
return Lists.newArrayList(index.invoke().properties.get(name)); return Lists.newArrayList(index.invoke().properties.get(ResolveSessionUtils.safeNameForLazyResolve(name)));
} }
@NotNull @NotNull
@Override @Override
public Collection<JetClassLikeInfo> getClassOrObjectDeclarations(@NotNull Name name) { public Collection<JetClassLikeInfo> getClassOrObjectDeclarations(@NotNull Name name) {
return index.invoke().classesAndObjects.get(name); return index.invoke().classesAndObjects.get(ResolveSessionUtils.safeNameForLazyResolve(name));
} }
} }
@@ -42,8 +42,6 @@ import org.jetbrains.jet.utils.Printer;
import java.util.*; import java.util.*;
import static org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils.safeNameForLazyResolve;
public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, DP extends DeclarationProvider> implements JetScope { public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, DP extends DeclarationProvider> implements JetScope {
protected final ResolveSession resolveSession; protected final ResolveSession resolveSession;
protected final BindingTrace trace; protected final BindingTrace trace;
@@ -228,19 +226,19 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
for (JetDeclaration declaration : declarations) { for (JetDeclaration declaration : declarations) {
if (declaration instanceof JetClassOrObject) { if (declaration instanceof JetClassOrObject) {
JetClassOrObject classOrObject = (JetClassOrObject) declaration; JetClassOrObject classOrObject = (JetClassOrObject) declaration;
result.addAll(classDescriptors.invoke(safeNameForLazyResolve(classOrObject.getNameAsName()))); result.addAll(classDescriptors.invoke(classOrObject.getNameAsSafeName()));
} }
else if (declaration instanceof JetFunction) { else if (declaration instanceof JetFunction) {
JetFunction function = (JetFunction) declaration; JetFunction function = (JetFunction) declaration;
result.addAll(getFunctions(safeNameForLazyResolve(function))); result.addAll(getFunctions(function.getNameAsSafeName()));
} }
else if (declaration instanceof JetProperty) { else if (declaration instanceof JetProperty) {
JetProperty property = (JetProperty) declaration; JetProperty property = (JetProperty) declaration;
result.addAll(getProperties(safeNameForLazyResolve(property))); result.addAll(getProperties(property.getNameAsSafeName()));
} }
else if (declaration instanceof JetParameter) { else if (declaration instanceof JetParameter) {
JetParameter parameter = (JetParameter) declaration; JetParameter parameter = (JetParameter) declaration;
result.addAll(getProperties(safeNameForLazyResolve(parameter))); result.addAll(getProperties(parameter.getNameAsSafeName()));
} }
else if (declaration instanceof JetScript) { else if (declaration instanceof JetScript) {
result.addAll(classDescriptors.invoke(ScriptNameUtil.classNameForScript((JetScript) declaration).shortName())); result.addAll(classDescriptors.invoke(ScriptNameUtil.classNameForScript((JetScript) declaration).shortName()));
@@ -20,8 +20,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetDeclaration; import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.lazy.declarations.PackageMemberDeclarationProvider; import org.jetbrains.jet.lang.resolve.lazy.declarations.PackageMemberDeclarationProvider;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
@@ -45,13 +43,6 @@ public class LazyPackageMemberScope extends AbstractLazyMemberScope<PackageFragm
return null; return null;
} }
@Override
public ClassifierDescriptor getClassifier(@NotNull Name name) {
// TODO: creating an FqName every time may be a performance problem
Name actualName = resolveSession.resolveClassifierAlias(DescriptorUtils.getFqNameSafe(thisDescriptor), name);
return super.getClassifier(actualName);
}
@NotNull @NotNull
@Override @Override
protected JetScope getScopeForMemberDeclarationResolution(JetDeclaration declaration) { protected JetScope getScopeForMemberDeclarationResolution(JetDeclaration declaration) {
@@ -25,7 +25,6 @@ import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.lazy.ForceResolveUtil; import org.jetbrains.jet.lang.resolve.lazy.ForceResolveUtil;
import org.jetbrains.jet.lang.resolve.lazy.LazyEntity; import org.jetbrains.jet.lang.resolve.lazy.LazyEntity;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
@@ -45,7 +44,7 @@ public class LazyTypeParameterDescriptor extends AbstractLazyTypeParameterDescri
super( super(
resolveSession.getStorageManager(), resolveSession.getStorageManager(),
containingDeclaration, containingDeclaration,
ResolveSessionUtils.safeNameForLazyResolve(jetTypeParameter.getNameAsName()), jetTypeParameter.getNameAsSafeName(),
jetTypeParameter.getVariance(), jetTypeParameter.getVariance(),
jetTypeParameter.hasModifier(JetTokens.REIFIED_KEYWORD), jetTypeParameter.hasModifier(JetTokens.REIFIED_KEYWORD),
index index
@@ -0,0 +1,17 @@
// !DIAGNOSTICS: -REDECLARATION
class C {
fun<!SYNTAX!><!> () {
}
val<!SYNTAX!><!> : Int = 1
class<!SYNTAX!><!> {}
enum class<!SYNTAX!><!> {}
}
class C1<in<!SYNTAX!>><!><!SYNTAX!><!> {}
class C2(val<!SYNTAX!><!>) {}
@@ -0,0 +1,26 @@
// !DIAGNOSTICS: -REDECLARATION
package<!SYNTAX!><!>
fun<!SYNTAX!><!> () {
}
val<!SYNTAX!><!> : Int = 1
class<!SYNTAX!><!> {
}
trait<!SYNTAX!><!> {
}
object <!SYNTAX!><!>{
}
enum class<!SYNTAX!><!> {}
annotation class<!SYNTAX!><!> <!ANNOTATION_CLASS_WITH_BODY!>{}<!>
@@ -5911,6 +5911,16 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/diagnostics/tests/recovery"), Pattern.compile("^(.+)\\.kt$"), true); JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/diagnostics/tests/recovery"), Pattern.compile("^(.+)\\.kt$"), true);
} }
@TestMetadata("namelessMembers.kt")
public void testNamelessMembers() throws Exception {
doTest("compiler/testData/diagnostics/tests/recovery/namelessMembers.kt");
}
@TestMetadata("namelessToplevelDeclarations.kt")
public void testNamelessToplevelDeclarations() throws Exception {
doTest("compiler/testData/diagnostics/tests/recovery/namelessToplevelDeclarations.kt");
}
} }
@TestMetadata("compiler/testData/diagnostics/tests/redeclarations") @TestMetadata("compiler/testData/diagnostics/tests/redeclarations")
@@ -278,6 +278,7 @@ fun main(args: Array<String>) {
testClass(javaClass<AbstractJetPsiCheckerTest>()) { testClass(javaClass<AbstractJetPsiCheckerTest>()) {
model("checker", recursive = false) model("checker", recursive = false)
model("checker/regression") model("checker/regression")
model("checker/recovery")
model("checker/rendering") model("checker/rendering")
model("checker/duplicateJvmSignature") model("checker/duplicateJvmSignature")
model("checker/infos", testMethod = "doTestWithInfos") model("checker/infos", testMethod = "doTestWithInfos")
@@ -29,6 +29,7 @@ import org.jetbrains.jet.plugin.stubindex.JetTopLevelPropertiesFqnNameIndex
import org.jetbrains.jet.plugin.stubindex.PackageIndexUtil import org.jetbrains.jet.plugin.stubindex.PackageIndexUtil
import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo
import org.jetbrains.jet.lang.resolve.lazy.data.JetClassInfoUtil import org.jetbrains.jet.lang.resolve.lazy.data.JetClassInfoUtil
import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils
public class StubBasedPackageMemberDeclarationProvider( public class StubBasedPackageMemberDeclarationProvider(
private val fqName: FqName, private val fqName: FqName,
@@ -66,7 +67,7 @@ public class StubBasedPackageMemberDeclarationProvider(
} }
private fun childName(name: Name): String { private fun childName(name: Name): String {
return fqName.child(name).asString() return fqName.child(ResolveSessionUtils.safeNameForLazyResolve(name)).asString()
} }
} }
@@ -0,0 +1,15 @@
class C {
fun<error> </error>() {
}
<error>val<error> </error>: Int = 1</error>
<error>class<error> </error>{}</error>
<error>enum class<error> </error>{}</error>
}
class C1<in<error>></error><error> </error>{}
class C2(val<error>)</error> {}
@@ -0,0 +1,24 @@
package<EOLError></EOLError>
fun<error> </error>() {
}
val<error> </error>: Int = 1
class<error> </error>{
}
trait<error> </error>{
}
object <error>{</error>
}
enum class<error> </error>{}
annotation class<error> </error><error>{}</error>
@@ -30,7 +30,7 @@ import org.jetbrains.jet.checkers.AbstractJetPsiCheckerTest;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ /** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all") @SuppressWarnings("all")
@InnerTestClasses({JetPsiCheckerTestGenerated.Checker.class, JetPsiCheckerTestGenerated.Regression.class, JetPsiCheckerTestGenerated.Rendering.class, JetPsiCheckerTestGenerated.DuplicateJvmSignature.class, JetPsiCheckerTestGenerated.Infos.class}) @InnerTestClasses({JetPsiCheckerTestGenerated.Checker.class, JetPsiCheckerTestGenerated.Regression.class, JetPsiCheckerTestGenerated.Recovery.class, JetPsiCheckerTestGenerated.Rendering.class, JetPsiCheckerTestGenerated.DuplicateJvmSignature.class, JetPsiCheckerTestGenerated.Infos.class})
public class JetPsiCheckerTestGenerated extends AbstractJetPsiCheckerTest { public class JetPsiCheckerTestGenerated extends AbstractJetPsiCheckerTest {
@TestMetadata("idea/testData/checker") @TestMetadata("idea/testData/checker")
public static class Checker extends AbstractJetPsiCheckerTest { public static class Checker extends AbstractJetPsiCheckerTest {
@@ -408,6 +408,24 @@ public class JetPsiCheckerTestGenerated extends AbstractJetPsiCheckerTest {
} }
@TestMetadata("idea/testData/checker/recovery")
public static class Recovery extends AbstractJetPsiCheckerTest {
public void testAllFilesPresentInRecovery() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/checker/recovery"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("namelessMembers.kt")
public void testNamelessMembers() throws Exception {
doTest("idea/testData/checker/recovery/namelessMembers.kt");
}
@TestMetadata("namelessToplevelDeclarations.kt")
public void testNamelessToplevelDeclarations() throws Exception {
doTest("idea/testData/checker/recovery/namelessToplevelDeclarations.kt");
}
}
@TestMetadata("idea/testData/checker/rendering") @TestMetadata("idea/testData/checker/rendering")
public static class Rendering extends AbstractJetPsiCheckerTest { public static class Rendering extends AbstractJetPsiCheckerTest {
public void testAllFilesPresentInRendering() throws Exception { public void testAllFilesPresentInRendering() throws Exception {
@@ -540,6 +558,7 @@ public class JetPsiCheckerTestGenerated extends AbstractJetPsiCheckerTest {
TestSuite suite = new TestSuite("JetPsiCheckerTestGenerated"); TestSuite suite = new TestSuite("JetPsiCheckerTestGenerated");
suite.addTestSuite(Checker.class); suite.addTestSuite(Checker.class);
suite.addTestSuite(Regression.class); suite.addTestSuite(Regression.class);
suite.addTestSuite(Recovery.class);
suite.addTestSuite(Rendering.class); suite.addTestSuite(Rendering.class);
suite.addTest(DuplicateJvmSignature.innerSuite()); suite.addTest(DuplicateJvmSignature.innerSuite());
suite.addTestSuite(Infos.class); suite.addTestSuite(Infos.class);