Merge remote branch 'origin/master'

This commit is contained in:
Andrey Breslav
2011-12-27 11:46:22 +04:00
27 changed files with 284 additions and 95 deletions
@@ -203,8 +203,10 @@ public class IntrinsicMethods {
private void declareIntrinsicProperty(String className, String methodName, IntrinsicMethod implementation) { private void declareIntrinsicProperty(String className, String methodName, IntrinsicMethod implementation) {
final JetScope numberScope = getClassMemberScope(className); final JetScope numberScope = getClassMemberScope(className);
final VariableDescriptor variable = numberScope.getVariable(methodName); Set<VariableDescriptor> properties = numberScope.getProperties(methodName);
myMethods.put(variable.getOriginal(), implementation); assert properties.size() == 1;
final VariableDescriptor property = properties.iterator().next();
myMethods.put(property.getOriginal(), implementation);
} }
private void declareIntrinsicFunction(String className, String functionName, int arity, IntrinsicMethod implementation) { private void declareIntrinsicFunction(String className, String functionName, int arity, IntrinsicMethod implementation) {
@@ -4,15 +4,13 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.psi.*; import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.TypeSubstitutor; import org.jetbrains.jet.lang.types.TypeSubstitutor;
import java.util.Collection; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
/** /**
* @author abreslav * @author abreslav
@@ -115,16 +113,25 @@ public class JavaClassMembersScope implements JetScope {
return null; return null;
} }
@NotNull
@Override @Override
public VariableDescriptor getVariable(@NotNull String name) { public Set<VariableDescriptor> getProperties(@NotNull String name) {
VariableDescriptor variableDescriptor = variables.get(name); VariableDescriptor variableDescriptor = variables.get(name);
if (variableDescriptor == null) { if (variableDescriptor == null) {
variableDescriptor = doGetVariable(name); variableDescriptor = doGetVariable(name);
variables.put(name, variableDescriptor); if (variableDescriptor != null) {
variables.put(name, variableDescriptor);
}
} }
return variableDescriptor; return variableDescriptor != null ? Collections.singleton(variableDescriptor) : Collections.<VariableDescriptor>emptySet();
} }
@Override
public VariableDescriptor getLocalVariable(@NotNull String name) {
return null;
}
@Nullable
private VariableDescriptor doGetVariable(String name) { private VariableDescriptor doGetVariable(String name) {
PsiField field = psiClass.findFieldByName(name, true); PsiField field = psiClass.findFieldByName(name, true);
if (field == null) return null; if (field == null) return null;
@@ -145,8 +145,8 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) { public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
properties.add(propertyDescriptor); properties.add(propertyDescriptor);
callableMembers.add(propertyDescriptor); callableMembers.add(propertyDescriptor);
scopeForMemberLookup.addVariableDescriptor(propertyDescriptor); scopeForMemberLookup.addPropertyDescriptor(propertyDescriptor);
scopeForMemberResolution.addVariableDescriptor(propertyDescriptor); scopeForMemberResolution.addPropertyDescriptor(propertyDescriptor);
} }
@Override @Override
@@ -49,8 +49,8 @@ public class NamespaceDescriptorImpl extends AbstractNamespaceDescriptorImpl imp
} }
@Override @Override
public void addPropertyDescriptor(@NotNull PropertyDescriptor variableDescriptor) { public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
memberScope.addVariableDescriptor(variableDescriptor); memberScope.addPropertyDescriptor(propertyDescriptor);
} }
@Override @Override
@@ -45,9 +45,15 @@ public abstract class AbstractScopeAdapter implements JetScope {
return getWorkerScope().getClassifier(name); return getWorkerScope().getClassifier(name);
} }
@NotNull
@Override @Override
public VariableDescriptor getVariable(@NotNull String name) { public Set<VariableDescriptor> getProperties(@NotNull String name) {
return getWorkerScope().getVariable(name); return getWorkerScope().getProperties(name);
}
@Override
public VariableDescriptor getLocalVariable(@NotNull String name) {
return getWorkerScope().getLocalVariable(name);
} }
@NotNull @NotNull
@@ -123,7 +123,7 @@ public class AnalyzingUtils {
@Override @Override
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) { public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
scope.addVariableDescriptor(propertyDescriptor); scope.addPropertyDescriptor(propertyDescriptor);
} }
@Override @Override
@@ -1,15 +1,19 @@
package org.jetbrains.jet.lang.resolve; package org.jetbrains.jet.lang.resolve;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull; 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.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import java.util.List; import java.util.*;
import java.util.Map;
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER; import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
@@ -77,6 +81,7 @@ public class DescriptorUtils {
return substituted; return substituted;
} }
@Nullable
@Override @Override
public JetType substitute(@NotNull JetType type, @NotNull Variance howThisTypeIsUsed) { public JetType substitute(@NotNull JetType type, @NotNull Variance howThisTypeIsUsed) {
TypeParameterDescriptor typeParameterDescriptor = typeConstructors.get(type.getConstructor()); TypeParameterDescriptor typeParameterDescriptor = typeConstructors.get(type.getConstructor());
@@ -196,4 +201,14 @@ public class DescriptorUtils {
} }
return false; return false;
} }
@Nullable
public static VariableDescriptor filterNonExtensionProperty(Set<VariableDescriptor> variables) {
for (VariableDescriptor variable : variables) {
if (!variable.getReceiverParameter().exists()) {
return variable;
}
}
return null;
}
} }
@@ -12,7 +12,6 @@ import org.jetbrains.jet.lang.types.JetType;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.diagnostics.Errors.*;
@@ -113,8 +112,8 @@ public class ImportsResolver {
namespaceScope.importFunctionAlias(aliasName, (FunctionDescriptor) descriptor); namespaceScope.importFunctionAlias(aliasName, (FunctionDescriptor) descriptor);
return; return;
} }
if (descriptor instanceof VariableDescriptor) { if (descriptor instanceof PropertyDescriptor) {
namespaceScope.importVariableAlias(aliasName, (VariableDescriptor) descriptor); namespaceScope.importVariableAlias(aliasName, (PropertyDescriptor) descriptor);
} }
} }
@@ -191,11 +190,9 @@ public class ImportsResolver {
ClassifierDescriptor classifierDescriptor = outerScope.getClassifier(referencedName); ClassifierDescriptor classifierDescriptor = outerScope.getClassifier(referencedName);
if (classifierDescriptor != null) descriptors.add(classifierDescriptor); if (classifierDescriptor != null) descriptors.add(classifierDescriptor);
Set<FunctionDescriptor> functionDescriptors = outerScope.getFunctions(referencedName); descriptors.addAll(outerScope.getFunctions(referencedName));
descriptors.addAll(functionDescriptors);
VariableDescriptor variableDescriptor = outerScope.getVariable(referencedName); descriptors.addAll(outerScope.getProperties(referencedName));
if (variableDescriptor != null) descriptors.add(variableDescriptor);
} }
if (!firstPhase) { if (!firstPhase) {
@@ -77,12 +77,12 @@ public class OverrideResolver {
@Nullable @Nullable
private PropertyDescriptor findPropertyOverridableBy(@NotNull PropertyDescriptor declaredProperty, @NotNull JetType supertype) { private PropertyDescriptor findPropertyOverridableBy(@NotNull PropertyDescriptor declaredProperty, @NotNull JetType supertype) {
PropertyDescriptor property = (PropertyDescriptor) supertype.getMemberScope().getVariable(declaredProperty.getName()); Set<VariableDescriptor> properties = supertype.getMemberScope().getProperties(declaredProperty.getName());
if (property == null) { for (VariableDescriptor property : properties) {
return null; assert property instanceof PropertyDescriptor;
} if (OverridingUtil.isOverridableBy(property, declaredProperty).isSuccess()) {
if (OverridingUtil.isOverridableBy(property, declaredProperty).isSuccess()) { return (PropertyDescriptor) property;
return property; }
} }
return null; return null;
} }
@@ -1,9 +1,13 @@
package org.jetbrains.jet.lang.resolve.calls; package org.jetbrains.jet.lang.resolve.calls;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetStandardClasses; import org.jetbrains.jet.lang.types.JetStandardClasses;
@@ -68,8 +72,11 @@ public class TaskPrioritizers {
} }
private void addVariableAsFunction(JetScope scope, String name, Set<FunctionDescriptor> functions, boolean receiverNeeded) { private void addVariableAsFunction(JetScope scope, String name, Set<FunctionDescriptor> functions, boolean receiverNeeded) {
VariableDescriptor variable = scope.getVariable(name); VariableDescriptor variable = scope.getLocalVariable(name);
if (variable != null && !variable.getReceiverParameter().exists()) { if (variable == null) {
variable = DescriptorUtils.filterNonExtensionProperty(scope.getProperties(name));
}
if (variable != null) {
JetType outType = variable.getOutType(); JetType outType = variable.getOutType();
if (outType != null && JetStandardClasses.isFunctionType(outType)) { if (outType != null && JetStandardClasses.isFunctionType(outType)) {
VariableAsFunctionDescriptor functionDescriptor = VariableAsFunctionDescriptor.create(variable); VariableAsFunctionDescriptor functionDescriptor = VariableAsFunctionDescriptor.create(variable);
@@ -86,36 +93,34 @@ public class TaskPrioritizers {
@NotNull @NotNull
@Override @Override
protected Collection<VariableDescriptor> getNonExtensionsByName(JetScope scope, String name) { protected Collection<VariableDescriptor> getNonExtensionsByName(JetScope scope, String name) {
VariableDescriptor variable = scope.getVariable(name); VariableDescriptor descriptor = scope.getLocalVariable(name);
if (variable != null && !variable.getReceiverParameter().exists()) { if (descriptor == null) {
return Collections.singleton(variable); descriptor = DescriptorUtils.filterNonExtensionProperty(scope.getProperties(name));
} }
return Collections.emptyList(); if (descriptor == null) return Collections.emptyList();
return Collections.singleton(descriptor);
} }
@NotNull @NotNull
@Override @Override
protected Collection<VariableDescriptor> getMembersByName(@NotNull JetType receiverType, String name) { protected Collection<VariableDescriptor> getMembersByName(@NotNull JetType receiverType, String name) {
VariableDescriptor variable = receiverType.getMemberScope().getVariable(name); return receiverType.getMemberScope().getProperties(name);
if (variable != null) {
return Collections.singleton(variable);
}
return Collections.emptyList();
} }
@NotNull @NotNull
@Override @Override
protected Collection<VariableDescriptor> getExtensionsByName(JetScope scope, String name) { protected Collection<VariableDescriptor> getExtensionsByName(JetScope scope, String name) {
VariableDescriptor variable = scope.getVariable(name); return Collections2.filter(scope.getProperties(name), new Predicate<VariableDescriptor>() {
if (variable != null && variable.getReceiverParameter().exists()) { @Override
return Collections.singleton(variable); public boolean apply(@Nullable VariableDescriptor variableDescriptor) {
} return (variableDescriptor != null) && variableDescriptor.getReceiverParameter().exists();
return Collections.emptyList(); }
});
} }
}; };
/*package*/ static TaskPrioritizer<VariableDescriptor> PROPERTY_TASK_PRIORITIZER = new TaskPrioritizer<VariableDescriptor>() { /*package*/ static TaskPrioritizer<VariableDescriptor> PROPERTY_TASK_PRIORITIZER = new TaskPrioritizer<VariableDescriptor>() {
private Collection<VariableDescriptor> filterProperties(Collection<VariableDescriptor> variableDescriptors) { private Collection<VariableDescriptor> filterProperties(Collection<? extends VariableDescriptor> variableDescriptors) {
ArrayList<VariableDescriptor> properties = Lists.newArrayList(); ArrayList<VariableDescriptor> properties = Lists.newArrayList();
for (VariableDescriptor descriptor : variableDescriptors) { for (VariableDescriptor descriptor : variableDescriptors) {
if (descriptor instanceof PropertyDescriptor) { if (descriptor instanceof PropertyDescriptor) {
@@ -43,10 +43,20 @@ public class ChainedScope implements JetScope {
return null; return null;
} }
@NotNull
@Override @Override
public VariableDescriptor getVariable(@NotNull String name) { public Set<VariableDescriptor> getProperties(@NotNull String name) {
Set<VariableDescriptor> properties = Sets.newLinkedHashSet();
for (JetScope jetScope : scopeChain) { for (JetScope jetScope : scopeChain) {
VariableDescriptor variable = jetScope.getVariable(name); properties.addAll(jetScope.getProperties(name));
}
return properties;
}
@Override
public VariableDescriptor getLocalVariable(@NotNull String name) {
for (JetScope jetScope : scopeChain) {
VariableDescriptor variable = jetScope.getLocalVariable(name);
if (variable != null) { if (variable != null) {
return variable; return variable;
} }
@@ -32,8 +32,11 @@ public interface JetScope {
@Nullable @Nullable
NamespaceDescriptor getNamespace(@NotNull String name); NamespaceDescriptor getNamespace(@NotNull String name);
@NotNull
Set<VariableDescriptor> getProperties(@NotNull String name);
@Nullable @Nullable
VariableDescriptor getVariable(@NotNull String name); VariableDescriptor getLocalVariable(@NotNull String name);
@NotNull @NotNull
Set<FunctionDescriptor> getFunctions(@NotNull String name); Set<FunctionDescriptor> getFunctions(@NotNull String name);
@@ -18,8 +18,14 @@ public abstract class JetScopeImpl implements JetScope {
return null; return null;
} }
@NotNull
@Override @Override
public VariableDescriptor getVariable(@NotNull String name) { public Set<VariableDescriptor> getProperties(@NotNull String name) {
return Collections.emptySet();
}
@Override
public VariableDescriptor getLocalVariable(@NotNull String name) {
return null; return null;
} }
@@ -60,9 +60,15 @@ public class SubstitutingScope implements JetScope {
return result; return result;
} }
@NotNull
@Override @Override
public VariableDescriptor getVariable(@NotNull String name) { public Set<VariableDescriptor> getProperties(@NotNull String name) {
return substitute(workerScope.getVariable(name)); return substitute(workerScope.getProperties(name));
}
@Override
public VariableDescriptor getLocalVariable(@NotNull String name) {
return substitute(workerScope.getLocalVariable(name));
} }
@Override @Override
@@ -21,6 +21,8 @@ public interface WritableScope extends JetScope {
void addVariableDescriptor(@NotNull VariableDescriptor variableDescriptor); void addVariableDescriptor(@NotNull VariableDescriptor variableDescriptor);
void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor);
void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor); void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor);
void addTypeParameterDescriptor(@NotNull TypeParameterDescriptor typeParameterDescriptor); void addTypeParameterDescriptor(@NotNull TypeParameterDescriptor typeParameterDescriptor);
@@ -50,5 +52,5 @@ public interface WritableScope extends JetScope {
void importFunctionAlias(@NotNull String aliasName, @NotNull FunctionDescriptor functionDescriptor); void importFunctionAlias(@NotNull String aliasName, @NotNull FunctionDescriptor functionDescriptor);
void importVariableAlias(@NotNull String aliasName, @NotNull VariableDescriptor variableDescriptor); void importVariableAlias(@NotNull String aliasName, @NotNull PropertyDescriptor variableDescriptor);
} }
@@ -8,6 +8,7 @@ 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.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.util.CommonSuppliers; import org.jetbrains.jet.util.CommonSuppliers;
import java.util.*; import java.util.*;
@@ -32,6 +33,9 @@ public class WritableScopeImpl extends WritableScopeWithImports {
@Nullable @Nullable
private Map<String, DeclarationDescriptor> variableClassOrNamespaceDescriptors; private Map<String, DeclarationDescriptor> variableClassOrNamespaceDescriptors;
@Nullable
private SetMultimap<String, VariableDescriptor> propertyGroups;
@Nullable @Nullable
private Map<String, NamespaceDescriptor> namespaceAliases; private Map<String, NamespaceDescriptor> namespaceAliases;
@@ -85,10 +89,10 @@ public class WritableScopeImpl extends WritableScopeWithImports {
} }
@Override @Override
public void importVariableAlias(@NotNull String aliasName, @NotNull VariableDescriptor variableDescriptor) { public void importVariableAlias(@NotNull String aliasName, @NotNull PropertyDescriptor variableDescriptor) {
checkMayWrite(); checkMayWrite();
addVariableDescriptor(variableDescriptor); addPropertyDescriptor(variableDescriptor);
super.importVariableAlias(aliasName, variableDescriptor); super.importVariableAlias(aliasName, variableDescriptor);
} }
@@ -165,35 +169,69 @@ public class WritableScopeImpl extends WritableScopeWithImports {
@Override @Override
public void addVariableDescriptor(@NotNull VariableDescriptor variableDescriptor) { public void addVariableDescriptor(@NotNull VariableDescriptor variableDescriptor) {
addVariableDescriptor(variableDescriptor, false);
}
@Override
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
addVariableDescriptor(propertyDescriptor, true);
}
private void addVariableDescriptor(@NotNull VariableDescriptor variableDescriptor, boolean isProperty) {
checkMayWrite(); checkMayWrite();
Map<String, DeclarationDescriptor> variableClassOrNamespaceDescriptors = getVariableClassOrNamespaceDescriptors(); String name = variableDescriptor.getName();
DeclarationDescriptor existingDescriptor = variableClassOrNamespaceDescriptors.get(variableDescriptor.getName()); if (isProperty) {
if (existingDescriptor != null) { checkForPropertyRedeclaration(name, variableDescriptor);
redeclarationHandler.handleRedeclaration(existingDescriptor, variableDescriptor); getPropertyGroups().put(name, variableDescriptor);
}
if (!variableDescriptor.getReceiverParameter().exists()) {
checkForRedeclaration(name, variableDescriptor);
// TODO : Should this always happen?
getVariableClassOrNamespaceDescriptors().put(name, variableDescriptor);
} }
// TODO : Should this always happen?
variableClassOrNamespaceDescriptors.put(variableDescriptor.getName(), variableDescriptor);
allDescriptors.add(variableDescriptor); allDescriptors.add(variableDescriptor);
} }
@NotNull
@Override @Override
public VariableDescriptor getVariable(@NotNull String name) { public Set<VariableDescriptor> getProperties(@NotNull String name) {
checkMayRead();
Set<VariableDescriptor> result = Sets.newLinkedHashSet(getPropertyGroups().get(name));
result.addAll(getWorkerScope().getProperties(name));
result.addAll(super.getProperties(name));
return result;
}
@Override
public VariableDescriptor getLocalVariable(@NotNull String name) {
checkMayRead(); checkMayRead();
Map<String, DeclarationDescriptor> variableClassOrNamespaceDescriptors = getVariableClassOrNamespaceDescriptors(); Map<String, DeclarationDescriptor> variableClassOrNamespaceDescriptors = getVariableClassOrNamespaceDescriptors();
DeclarationDescriptor descriptor = variableClassOrNamespaceDescriptors.get(name); DeclarationDescriptor descriptor = variableClassOrNamespaceDescriptors.get(name);
if (descriptor instanceof VariableDescriptor) { if (descriptor instanceof VariableDescriptor && !getPropertyGroups().get(name).contains(descriptor)) {
return (VariableDescriptor) descriptor; return (VariableDescriptor) descriptor;
} }
VariableDescriptor variableDescriptor = getWorkerScope().getVariable(name); VariableDescriptor variableDescriptor = getWorkerScope().getLocalVariable(name);
if (variableDescriptor != null) { if (variableDescriptor != null) {
return variableDescriptor; return variableDescriptor;
} }
return super.getVariable(name); return super.getLocalVariable(name);
} }
@NotNull
private SetMultimap<String, VariableDescriptor> getPropertyGroups() {
if (propertyGroups == null) {
propertyGroups = CommonSuppliers.newLinkedHashSetHashSetMultimap();
}
return propertyGroups;
}
@NotNull @NotNull
private SetMultimap<String, FunctionDescriptor> getFunctionGroups() { private SetMultimap<String, FunctionDescriptor> getFunctionGroups() {
if (functionGroups == null) { if (functionGroups == null) {
@@ -274,6 +312,18 @@ public class WritableScopeImpl extends WritableScopeWithImports {
getVariableClassOrNamespaceDescriptors().put(name, variableDescriptor); getVariableClassOrNamespaceDescriptors().put(name, variableDescriptor);
allDescriptors.add(variableDescriptor); allDescriptors.add(variableDescriptor);
} }
private void checkForPropertyRedeclaration(String name, VariableDescriptor variableDescriptor) {
Set<VariableDescriptor> properties = getPropertyGroups().get(name);
ReceiverDescriptor receiverParameter = variableDescriptor.getReceiverParameter();
for (VariableDescriptor oldProperty : properties) {
ReceiverDescriptor receiverParameterForOldVariable = oldProperty.getReceiverParameter();
if (((receiverParameter.exists() && receiverParameterForOldVariable.exists()) &&
(JetTypeChecker.INSTANCE.equalTypes(receiverParameter.getType(), receiverParameterForOldVariable.getType())))) {
redeclarationHandler.handleRedeclaration(oldProperty, variableDescriptor);
}
}
}
private void checkForRedeclaration(String name, DeclarationDescriptor classifierDescriptor) { private void checkForRedeclaration(String name, DeclarationDescriptor classifierDescriptor) {
DeclarationDescriptor originalDescriptor = getVariableClassOrNamespaceDescriptors().get(name); DeclarationDescriptor originalDescriptor = getVariableClassOrNamespaceDescriptors().get(name);
@@ -364,7 +414,7 @@ public class WritableScopeImpl extends WritableScopeWithImports {
super.getImplicitReceiversHierarchy(result); super.getImplicitReceiversHierarchy(result);
} }
@SuppressWarnings({"NullableProblems"}) // @SuppressWarnings({"NullableProblems"})
@NotNull @NotNull
private Map<String, PropertyDescriptor> getPropertyDescriptorsByFieldNames() { private Map<String, PropertyDescriptor> getPropertyDescriptorsByFieldNames() {
if (propertyDescriptorsByFieldNames == null) { if (propertyDescriptorsByFieldNames == null) {
@@ -6,10 +6,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/** /**
* @author abreslav * @author abreslav
@@ -96,13 +93,25 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement
} }
} }
@NotNull
@Override @Override
public VariableDescriptor getVariable(@NotNull String name) { public Set<VariableDescriptor> getProperties(@NotNull String name) {
checkMayRead();
Set<VariableDescriptor> properties = Sets.newLinkedHashSet();
for (JetScope imported : getImports()) {
properties.addAll(imported.getProperties(name));
}
return properties;
}
@Override
public VariableDescriptor getLocalVariable(@NotNull String name) {
checkMayRead(); checkMayRead();
// Meaningful lookup goes here // Meaningful lookup goes here
for (JetScope imported : getImports()) { for (JetScope imported : getImports()) {
VariableDescriptor importedDescriptor = imported.getVariable(name); VariableDescriptor importedDescriptor = imported.getLocalVariable(name);
if (importedDescriptor != null) { if (importedDescriptor != null) {
return importedDescriptor; return importedDescriptor;
} }
@@ -184,7 +193,7 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement
} }
@Override @Override
public void importVariableAlias(@NotNull String aliasName, @NotNull VariableDescriptor variableDescriptor) { public void importVariableAlias(@NotNull String aliasName, @NotNull PropertyDescriptor variableDescriptor) {
checkMayWrite(); checkMayWrite();
getCurrentIndividualImportScope().addVariableAlias(aliasName, variableDescriptor); getCurrentIndividualImportScope().addVariableAlias(aliasName, variableDescriptor);
@@ -71,17 +71,29 @@ public class WriteThroughScope extends WritableScopeWithImports {
} }
@Override @Override
@Nullable @NotNull
public VariableDescriptor getVariable(@NotNull String name) { public Set<VariableDescriptor> getProperties(@NotNull String name) {
checkMayRead(); checkMayRead();
VariableDescriptor variable = writableWorker.getVariable(name); Set<VariableDescriptor> properties = Sets.newLinkedHashSet();
properties.addAll(writableWorker.getProperties(name));
properties.addAll(getWorkerScope().getProperties(name));
properties.addAll(super.getProperties(name)); //imports
return properties;
}
@Override
@Nullable
public VariableDescriptor getLocalVariable(@NotNull String name) {
checkMayRead();
VariableDescriptor variable = writableWorker.getLocalVariable(name);
if (variable != null) return variable; if (variable != null) return variable;
variable = getWorkerScope().getVariable(name); variable = getWorkerScope().getLocalVariable(name);
if (variable != null) return variable; if (variable != null) return variable;
return super.getVariable(name); // Imports return super.getLocalVariable(name); // Imports
} }
@Override @Override
@@ -126,6 +138,13 @@ public class WriteThroughScope extends WritableScopeWithImports {
writableWorker.addVariableDescriptor(variableDescriptor); writableWorker.addVariableDescriptor(variableDescriptor);
} }
@Override
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
checkMayWrite();
writableWorker.addPropertyDescriptor(propertyDescriptor);
}
@Override @Override
public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) { public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) {
checkMayWrite(); checkMayWrite();
@@ -22,8 +22,14 @@ public class ErrorUtils {
return ERROR_CLASS; return ERROR_CLASS;
} }
@NotNull
@Override @Override
public VariableDescriptor getVariable(@NotNull String name) { public Set<VariableDescriptor> getProperties(@NotNull String name) {
return ERROR_PROPERTY_GROUP;
}
@Override
public VariableDescriptor getLocalVariable(@NotNull String name) {
return ERROR_PROPERTY; return ERROR_PROPERTY;
} }
@@ -111,6 +117,7 @@ public class ErrorUtils {
ReceiverDescriptor.NO_RECEIVER, ReceiverDescriptor.NO_RECEIVER,
"<ERROR PROPERTY>", "<ERROR PROPERTY>",
ERROR_PROPERTY_TYPE, ERROR_PROPERTY_TYPE); ERROR_PROPERTY_TYPE, ERROR_PROPERTY_TYPE);
private static final Set<VariableDescriptor> ERROR_PROPERTY_GROUP = Collections.singleton(ERROR_PROPERTY);
private static FunctionDescriptor createErrorFunction(List<TypeParameterDescriptor> typeParameters, List<JetType> positionedValueArgumentTypes) { private static FunctionDescriptor createErrorFunction(List<TypeParameterDescriptor> typeParameters, List<JetType> positionedValueArgumentTypes) {
FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), "<ERROR FUNCTION>"); FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), "<ERROR FUNCTION>");
@@ -585,10 +585,14 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) selectorExpression; JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) selectorExpression;
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace); TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace);
OverloadResolutionResults<VariableDescriptor> variableDescriptor = context.replaceBindingTrace(temporaryTrace).resolveSimpleProperty(receiver, callOperationNode, nameExpression); OverloadResolutionResults<VariableDescriptor> resolutionResult = context.replaceBindingTrace(temporaryTrace).resolveSimpleProperty(receiver, callOperationNode, nameExpression);
if (variableDescriptor.isSuccess()) { if (resolutionResult.isSuccess()) {
temporaryTrace.commit(); temporaryTrace.commit();
return variableDescriptor.getResultingDescriptor().getOutType(); return resolutionResult.getResultingDescriptor().getOutType();
}
if (resolutionResult.isAmbiguity()) {
temporaryTrace.commit();
return null;
} }
ExpressionTypingContext newContext = receiver.exists() ? context.replaceScope(receiver.getType().getMemberScope()) : context; ExpressionTypingContext newContext = receiver.exists() ? context.replaceScope(receiver.getType().getMemberScope()) : context;
JetType jetType = lookupNamespaceOrClassObject(nameExpression, nameExpression.getReferencedName(), newContext); JetType jetType = lookupNamespaceOrClassObject(nameExpression, nameExpression.getReferencedName(), newContext);
@@ -20,10 +20,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.*; import static org.jetbrains.jet.lang.resolve.BindingContext.*;
@@ -238,7 +235,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
{ {
// http://youtrack.jetbrains.net/issue/KT-527 // http://youtrack.jetbrains.net/issue/KT-527
VariableDescriptor olderVariable = context.scope.getVariable(variableDescriptor.getName()); VariableDescriptor olderVariable = context.scope.getLocalVariable(variableDescriptor.getName());
if (olderVariable != null && DescriptorUtils.isLocal(context.scope.getContainingDeclaration(), olderVariable)) { if (olderVariable != null && DescriptorUtils.isLocal(context.scope.getContainingDeclaration(), olderVariable)) {
context.trace.report(Errors.NAME_SHADOWING.on(variableDescriptor, context.trace.getBindingContext())); context.trace.report(Errors.NAME_SHADOWING.on(variableDescriptor, context.trace.getBindingContext()));
} }
@@ -326,8 +323,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
@Nullable @Nullable
private VariableDescriptor checkHasNextPropertySupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) { private VariableDescriptor checkHasNextPropertySupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) {
VariableDescriptor hasNextProperty = iteratorType.getMemberScope().getVariable("hasNext"); VariableDescriptor hasNextProperty = DescriptorUtils.filterNonExtensionProperty(iteratorType.getMemberScope().getProperties("hasNext"));
// TODO :extension properties
if (hasNextProperty == null) { if (hasNextProperty == null) {
return null; return null;
} else { } else {
@@ -63,7 +63,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
ClassDescriptor classDescriptor = context.trace.getBindingContext().get(BindingContext.CLASS, declaration); ClassDescriptor classDescriptor = context.trace.getBindingContext().get(BindingContext.CLASS, declaration);
if (classDescriptor != null) { if (classDescriptor != null) {
PropertyDescriptor propertyDescriptor = context.getDescriptorResolver().resolveObjectDeclarationAsPropertyDescriptor(scope.getContainingDeclaration(), declaration, classDescriptor); PropertyDescriptor propertyDescriptor = context.getDescriptorResolver().resolveObjectDeclarationAsPropertyDescriptor(scope.getContainingDeclaration(), declaration, classDescriptor);
scope.addVariableDescriptor(propertyDescriptor); scope.addPropertyDescriptor(propertyDescriptor);
} }
return DataFlowUtils.checkStatementType(declaration, context); return DataFlowUtils.checkStatementType(declaration, context);
} }
@@ -93,7 +93,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
} }
{ {
VariableDescriptor olderVariable = scope.getVariable(propertyDescriptor.getName()); VariableDescriptor olderVariable = scope.getLocalVariable(propertyDescriptor.getName());
if (olderVariable != null && DescriptorUtils.isLocal(propertyDescriptor.getContainingDeclaration(), olderVariable)) { if (olderVariable != null && DescriptorUtils.isLocal(propertyDescriptor.getContainingDeclaration(), olderVariable)) {
context.trace.report(Errors.NAME_SHADOWING.on(propertyDescriptor, context.trace.getBindingContext())); context.trace.report(Errors.NAME_SHADOWING.on(propertyDescriptor, context.trace.getBindingContext()));
} }
@@ -67,7 +67,17 @@ abstract class Range1() {
abstract fun iterator() : Iterator<Int> abstract fun iterator() : Iterator<Int>
} }
fun test(notRange1: NotRange1, notRange2: NotRange2, notRange3: NotRange3, notRange4: NotRange4, notRange5: NotRange5, notRange6: NotRange6, notRange7: NotRange7, range0: Range0, range1: Range1) { abstract class ImproperIterator5 {
abstract val String.hasNext : Boolean
abstract fun next() : Int
}
abstract class NotRange8() {
abstract fun iterator() : ImproperIterator5
}
fun test(notRange1: NotRange1, notRange2: NotRange2, notRange3: NotRange3, notRange4: NotRange4, notRange5: NotRange5, notRange6: NotRange6, notRange7: NotRange7, notRange8: NotRange8, range0: Range0, range1: Range1) {
for (i in <!ITERATOR_MISSING!>notRange1<!>); for (i in <!ITERATOR_MISSING!>notRange1<!>);
for (i in <!HAS_NEXT_MISSING, NEXT_MISSING!>notRange2<!>); for (i in <!HAS_NEXT_MISSING, NEXT_MISSING!>notRange2<!>);
for (i in <!NEXT_MISSING!>notRange3<!>); for (i in <!NEXT_MISSING!>notRange3<!>);
@@ -75,6 +85,7 @@ fun test(notRange1: NotRange1, notRange2: NotRange2, notRange3: NotRange3, notRa
for (i in <!HAS_NEXT_FUNCTION_TYPE_MISMATCH!>notRange5<!>); for (i in <!HAS_NEXT_FUNCTION_TYPE_MISMATCH!>notRange5<!>);
for (i in <!HAS_NEXT_PROPERTY_AND_FUNCTION_AMBIGUITY!>notRange6<!>); for (i in <!HAS_NEXT_PROPERTY_AND_FUNCTION_AMBIGUITY!>notRange6<!>);
for (i in <!HAS_NEXT_FUNCTION_TYPE_MISMATCH!>notRange7<!>); for (i in <!HAS_NEXT_FUNCTION_TYPE_MISMATCH!>notRange7<!>);
for (i in <!HAS_NEXT_MISSING!>notRange8<!>);
for (i in range0); for (i in range0);
for (i in range1); for (i in range1);
@@ -0,0 +1,34 @@
//+JDK
//KT-819 Redeclaration error for extension properties with the same name and different receivers
import java.io.*
inline val InputStream.buffered : BufferedInputStream
get() = if(this is BufferedInputStream) this else BufferedInputStream(this)
inline val Reader.buffered : BufferedReader
get() = if(this is BufferedReader) this else BufferedReader(this)
//more tests
open class A() {
open fun String.foo() {}
open fun Int.foo() {}
open val String.foo = 0
open val Int.foo = 1
}
class B() : A() {
override fun String.foo() {}
override fun Int.foo() {}
override val String.foo = 0
override val Int.foo = 0
fun use(s: String) {
s.foo
s.foo()
}
}
@@ -670,7 +670,7 @@ public class JetTypeCheckerTest extends JetLiteFixture {
@Override @Override
public void visitProperty(JetProperty property) { public void visitProperty(JetProperty property) {
if (property.getPropertyTypeRef() != null) { if (property.getPropertyTypeRef() != null) {
memberDeclarations.addVariableDescriptor(descriptorResolver.resolvePropertyDescriptor(classDescriptor, parameterScope, property)); memberDeclarations.addPropertyDescriptor(descriptorResolver.resolvePropertyDescriptor(classDescriptor, parameterScope, property));
} else { } else {
// TODO : Caution: a cyclic dependency possible // TODO : Caution: a cyclic dependency possible
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();