Merge branch 'master' of ssh://git.labs.intellij.net/jet

This commit is contained in:
svtk
2011-09-13 12:20:48 +04:00
21 changed files with 385 additions and 161 deletions
@@ -26,6 +26,11 @@ public interface FunctionGroup extends Named {
public Set<FunctionDescriptor> getFunctionDescriptors() {
return Collections.emptySet();
}
@Override
public String toString() {
return "EMPTY";
}
};
@@ -42,7 +42,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
super(containingDeclaration);
this.scopeForMemberLookup = new WritableScopeImpl(JetScope.EMPTY, this, trace.getErrorHandler()).setDebugName("MemberLookup");
this.scopeForSupertypeResolution = new WritableScopeImpl(outerScope, this, trace.getErrorHandler()).setDebugName("SupertypeResolution");
this.scopeForMemberResolution = new WritableScopeImpl(new ChainedScope(this, scopeForMemberLookup, scopeForSupertypeResolution), this, trace.getErrorHandler()).setDebugName("MemberResolution");
this.scopeForMemberResolution = new WritableScopeImpl(scopeForSupertypeResolution, this, trace.getErrorHandler()).setDebugName("MemberResolution");
this.kind = kind;
}
@@ -87,6 +87,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
properties.add(propertyDescriptor);
scopeForMemberLookup.addVariableDescriptor(propertyDescriptor);
scopeForMemberResolution.addVariableDescriptor(propertyDescriptor);
}
@NotNull
@@ -98,6 +99,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) {
functions.add(functionDescriptor);
scopeForMemberLookup.addFunctionDescriptor(functionDescriptor);
scopeForMemberResolution.addFunctionDescriptor(functionDescriptor);
}
@NotNull
@@ -118,6 +120,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
@Override
public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) {
scopeForMemberLookup.addClassifierDescriptor(classDescriptor);
scopeForMemberResolution.addClassifierDescriptor(classDescriptor);
}
public void addSupertype(@NotNull JetType supertype) {
@@ -1,6 +1,6 @@
package org.jetbrains.jet.lang.parsing;
import com.intellij.lang.java.parser.JavaParserUtil.PsiBuilderAdapter;
import com.intellij.lang.impl.PsiBuilderAdapter;
/**
* @author abreslav
@@ -2,7 +2,7 @@ package org.jetbrains.jet.lang.parsing;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.java.parser.JavaParserUtil.PsiBuilderAdapter;
import com.intellij.lang.impl.PsiBuilderAdapter;
import com.intellij.psi.TokenType;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.jet.lexer.JetTokens;
@@ -41,89 +41,6 @@ public class ClassDescriptorResolver {
this.annotationResolver = new AnnotationResolver(semanticServices, trace);
}
@Nullable
public ClassDescriptor resolveClassDescriptor(@NotNull JetScope scope, @NotNull JetClass classElement) {
final ClassDescriptorImpl classDescriptor = new ClassDescriptorImpl(
scope.getContainingDeclaration(),
annotationResolver.resolveAnnotations(scope, classElement.getModifierList()),
JetPsiUtil.safeName(classElement.getName()));
trace.record(BindingContext.CLASS, classElement, classDescriptor);
final WritableScope parameterScope = new WritableScopeImpl(scope, classDescriptor, trace.getErrorHandler());
// This call has side-effects on the parameterScope (fills it in)
List<TypeParameterDescriptor> typeParameters
= resolveTypeParameters(classDescriptor, parameterScope, classElement.getTypeParameters());
resolveGenericBounds(classElement, parameterScope, typeParameters);
List<JetDelegationSpecifier> delegationSpecifiers = classElement.getDelegationSpecifiers();
// TODO : assuming that the hierarchy is acyclic
Collection<JetType> supertypes = delegationSpecifiers.isEmpty()
? Collections.singleton(JetStandardClasses.getAnyType())
: resolveDelegationSpecifiers(parameterScope, delegationSpecifiers, typeResolver);
// for (JetType supertype: supertypes) {
// if (supertype.getConstructor().isSealed()) {
// trace.getErrorHandler().genericError(classElement.getNameAsDeclaration().getNode(), "Class " + classElement.getName() + " can not extend final type " + supertype);
// }
// }
boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD);
final WritableScope memberDeclarations = new WritableScopeImpl(JetScope.EMPTY, classDescriptor, trace.getErrorHandler());
List<JetDeclaration> declarations = classElement.getDeclarations();
for (JetDeclaration declaration : declarations) {
declaration.accept(new JetVisitorVoid() {
@Override
public void visitProperty(JetProperty property) {
if (property.getPropertyTypeRef() != null) {
memberDeclarations.addVariableDescriptor(resolvePropertyDescriptor(classDescriptor, parameterScope, property));
} else {
// TODO : Caution: a cyclic dependency possible
throw new UnsupportedOperationException();
}
}
@Override
public void visitNamedFunction(JetNamedFunction function) {
if (function.getReturnTypeRef() != null) {
memberDeclarations.addFunctionDescriptor(resolveFunctionDescriptor(classDescriptor, parameterScope, function));
} else {
// TODO : Caution: a cyclic dependency possible
throw new UnsupportedOperationException();
}
}
@Override
public void visitJetElement(JetElement element) {
throw new UnsupportedOperationException(element.toString());
}
});
}
WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
classDescriptor.initialize(
!open,
typeParameters,
supertypes,
memberDeclarations,
constructors,
null
);
for (JetConstructor constructor : classElement.getSecondaryConstructors()) {
ConstructorDescriptorImpl functionDescriptor = resolveSecondaryConstructorDescriptor(memberDeclarations, classDescriptor, constructor);
functionDescriptor.setReturnType(classDescriptor.getDefaultType());
constructors.addFunction(functionDescriptor);
}
ConstructorDescriptorImpl primaryConstructorDescriptor = resolvePrimaryConstructorDescriptor(scope, classDescriptor, classElement);
if (primaryConstructorDescriptor != null) {
primaryConstructorDescriptor.setReturnType(classDescriptor.getDefaultType());
constructors.addFunction(primaryConstructorDescriptor);
classDescriptor.setPrimaryConstructor(primaryConstructorDescriptor);
}
return classDescriptor;
}
public void resolveMutableClassDescriptor(@NotNull JetClass classElement, @NotNull MutableClassDescriptor descriptor) {
// TODO : Where-clause
List<TypeParameterDescriptor> typeParameters = Lists.newArrayList();
@@ -398,7 +315,7 @@ public class ClassDescriptorResolver {
return jetType;
}
private Collection<JetType> resolveDelegationSpecifiers(JetScope extensibleScope, List<JetDelegationSpecifier> delegationSpecifiers, @NotNull TypeResolver resolver) {
public Collection<JetType> resolveDelegationSpecifiers(JetScope extensibleScope, List<JetDelegationSpecifier> delegationSpecifiers, @NotNull TypeResolver resolver) {
if (delegationSpecifiers.isEmpty()) {
return Collections.emptyList();
}
@@ -1,12 +1,15 @@
package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
import java.util.Collection;
import java.util.Map;
/**
* @author abreslav
@@ -15,7 +18,9 @@ public class SubstitutingScope implements JetScope {
private final JetScope workerScope;
private final TypeSubstitutor substitutor;
private Collection<DeclarationDescriptor> allDescriptors;
private Map<String, FunctionGroup> functionGroups = null;
private Collection<DeclarationDescriptor> allDescriptors = null;
public SubstitutingScope(JetScope workerScope, @NotNull TypeSubstitutor substitutor) {
this.workerScope = workerScope;
@@ -58,11 +63,27 @@ public class SubstitutingScope implements JetScope {
@NotNull
@Override
public FunctionGroup getFunctionGroup(@NotNull String name) {
FunctionGroup functionGroup = workerScope.getFunctionGroup(name);
if (substitutor.isEmpty() || functionGroup.isEmpty()) {
return functionGroup;
if (substitutor.isEmpty()) {
return workerScope.getFunctionGroup(name);
}
return new LazySubstitutingFunctionGroup(substitutor, functionGroup);
if (functionGroups == null) {
functionGroups = Maps.newHashMap();
}
FunctionGroup cachedGroup = functionGroups.get(name);
if (cachedGroup != null) {
return cachedGroup;
}
FunctionGroup functionGroup = workerScope.getFunctionGroup(name);
FunctionGroup result;
if (functionGroup.isEmpty()) {
result = FunctionGroup.EMPTY;
}
else {
result = new LazySubstitutingFunctionGroup(substitutor, functionGroup);
}
functionGroups.put(name, result);
return result;
}
@NotNull
@@ -291,7 +291,4 @@ public class TypeHierarchyResolver {
}
}
}
}
@@ -472,17 +472,9 @@ public class CallResolver {
@NotNull
private <Descriptor extends CallableDescriptor> OverloadResolutionResult<Descriptor> computeResultAndReportErrors(BindingTrace trace, TracingStrategy tracing, Map<Descriptor, Descriptor> successfulCandidates, Set<Descriptor> failedCandidates, Set<Descriptor> dirtyCandidates, Map<Descriptor, TemporaryBindingTrace> traces) {
// TODO : maybe it's better to filter overrides out first, and only then look for the maximally specific
if (successfulCandidates.size() > 0) {
if (successfulCandidates.size() == 1) {
Map.Entry<Descriptor, Descriptor> entry = successfulCandidates.entrySet().iterator().next();
Descriptor functionDescriptor = entry.getKey();
Descriptor result = entry.getValue();
TemporaryBindingTrace temporaryTrace = traces.get(functionDescriptor);
temporaryTrace.commit();
return OverloadResolutionResult.success(result);
}
else {
if (successfulCandidates.size() != 1) {
Map<Descriptor, Descriptor> cleanCandidates = Maps.newLinkedHashMap(successfulCandidates);
cleanCandidates.keySet().removeAll(dirtyCandidates);
if (cleanCandidates.isEmpty()) {
@@ -498,37 +490,41 @@ public class CallResolver {
return OverloadResolutionResult.success(maximallySpecificGenericsDiscriminated);
}
Set<Descriptor> noOverrides = filterOverrides(successfulCandidates.keySet());
if (dirtyCandidates.isEmpty()) {
StringBuilder stringBuilder = new StringBuilder();
for (Descriptor functionDescriptor : successfulCandidates.keySet()) {
stringBuilder.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append(" ");
}
tracing.reportOverallResolutionError(trace, "Overload resolution ambiguity: " + stringBuilder);
tracing.reportOverallResolutionError(trace, "Overload resolution ambiguity: "
+ makeErrorMessageForMultipleDescriptors(noOverrides));
}
tracing.recordAmbiguity(trace, successfulCandidates.keySet());
return OverloadResolutionResult.ambiguity(successfulCandidates.keySet());
tracing.recordAmbiguity(trace, noOverrides);
return OverloadResolutionResult.ambiguity(noOverrides);
}
else {
Map.Entry<Descriptor, Descriptor> entry = successfulCandidates.entrySet().iterator().next();
Descriptor functionDescriptor = entry.getKey();
Descriptor result = entry.getValue();
TemporaryBindingTrace temporaryTrace = traces.get(functionDescriptor);
temporaryTrace.commit();
return OverloadResolutionResult.success(result);
}
}
else if (!failedCandidates.isEmpty()) {
if (failedCandidates.size() == 1) {
Descriptor functionDescriptor = failedCandidates.iterator().next();
TemporaryBindingTrace temporaryTrace = traces.get(functionDescriptor);
temporaryTrace.commit();
return OverloadResolutionResult.singleFailedCandidate(failedCandidates.iterator().next());
}
else {
StringBuilder stringBuilder = new StringBuilder("\n");
for (Descriptor functionDescriptor : failedCandidates) {
stringBuilder.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append("\n");
if (failedCandidates.size() != 1) {
Set<Descriptor> noOverrides = filterOverrides(failedCandidates);
if (noOverrides.size() != 1) {
tracing.reportOverallResolutionError(trace, "None of the following functions can be called with the arguments supplied: "
+ makeErrorMessageForMultipleDescriptors(noOverrides));
tracing.recordAmbiguity(trace, noOverrides);
return OverloadResolutionResult.manyFailedCandidates(noOverrides);
}
tracing.reportOverallResolutionError(trace, "None of the following functions can be called with the arguments supplied: " + stringBuilder);
tracing.recordAmbiguity(trace, failedCandidates);
return OverloadResolutionResult.manyFailedCandidates(failedCandidates);
failedCandidates = noOverrides;
}
Descriptor functionDescriptor = failedCandidates.iterator().next();
TemporaryBindingTrace temporaryTrace = traces.get(functionDescriptor);
temporaryTrace.commit();
return OverloadResolutionResult.singleFailedCandidate(failedCandidates.iterator().next());
}
else {
tracing.reportUnresolvedReference(trace);
@@ -536,6 +532,28 @@ public class CallResolver {
}
}
private <Descriptor extends CallableDescriptor> StringBuilder makeErrorMessageForMultipleDescriptors(Set<Descriptor> candidates) {
StringBuilder stringBuilder = new StringBuilder("\n");
for (Descriptor functionDescriptor : candidates) {
stringBuilder.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append("\n");
}
return stringBuilder;
}
private <Descriptor extends CallableDescriptor> Set<Descriptor> filterOverrides(Set<Descriptor> candidateSet) {
Set<Descriptor> candidates = Sets.newLinkedHashSet();
outerLoop:
for (Descriptor me : candidateSet) {
for (Descriptor other : candidateSet) {
if (OverloadingConflictResolver.overrides(other, me)) {
continue outerLoop;
}
}
candidates.add(me);
}
return candidates;
}
private boolean checkValueArgumentTypes(JetScope scope, JetTypeInferrer.Services temporaryServices, Map<ValueArgument, ValueParameterDescriptor> argumentsToParameters, Flag dirty, Function<ValueParameterDescriptor, ValueParameterDescriptor> parameterMap) {
boolean result = true;
for (Map.Entry<ValueArgument, ValueParameterDescriptor> entry : argumentsToParameters.entrySet()) {
@@ -120,7 +120,7 @@ import java.util.Set;
return false;
}
private <Descriptor extends CallableDescriptor> boolean overrides(@NotNull Descriptor f, @NotNull Descriptor g) {
public static <Descriptor extends CallableDescriptor> boolean overrides(@NotNull Descriptor f, @NotNull Descriptor g) {
Set<CallableDescriptor> overriddenDescriptors = Sets.newHashSet();
getAllOverriddenDescriptors(f.getOriginal(), overriddenDescriptors);
CallableDescriptor originalG = g.getOriginal();
@@ -130,7 +130,7 @@ import java.util.Set;
return false;
}
private void getAllOverriddenDescriptors(@NotNull CallableDescriptor current, @NotNull Set<CallableDescriptor> overriddenDescriptors) {
private static void getAllOverriddenDescriptors(@NotNull CallableDescriptor current, @NotNull Set<CallableDescriptor> overriddenDescriptors) {
if (overriddenDescriptors.contains(current)) return;
for (CallableDescriptor descriptor : current.getOriginal().getOverriddenDescriptors()) {
getAllOverriddenDescriptors(descriptor, overriddenDescriptors);