Annotation resolver beautified a bit
This commit is contained in:
@@ -176,7 +176,6 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
|
||||
supertypes);
|
||||
scopeForMemberResolution.setThisType(getDefaultType());
|
||||
for (FunctionDescriptor functionDescriptor : constructors.getFunctionDescriptors()) {
|
||||
// functionDescriptor.getTypeParameters().addAll(typeParameters);
|
||||
((ConstructorDescriptorImpl) functionDescriptor).setReturnType(getDefaultType());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.jetbrains.jet.lang.psi;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -34,7 +35,8 @@ public class JetModifierList extends JetElement {
|
||||
}
|
||||
|
||||
public List<JetAnnotationEntry> getAnnotationEntries() {
|
||||
List<JetAnnotationEntry> answer = null;
|
||||
List<JetAnnotationEntry> entries = findChildrenByType(JetNodeTypes.ANNOTATION_ENTRY);
|
||||
List<JetAnnotationEntry> answer = entries.isEmpty() ? null : Lists.newArrayList(entries);
|
||||
for (JetAnnotation annotation : getAnnotations()) {
|
||||
if (answer == null) answer = new ArrayList<JetAnnotationEntry>();
|
||||
answer.addAll(annotation.getEntries());
|
||||
|
||||
@@ -4,25 +4,31 @@ import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||
import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetAnnotationEntry;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierList;
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.JetTypeInferrer;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.types.JetTypeInferrer.NO_EXPECTED_TYPE;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class AnnotationResolver {
|
||||
|
||||
private final BindingTrace trace;
|
||||
private final JetTypeInferrer typeInferrer;
|
||||
|
||||
public AnnotationResolver(JetSemanticServices semanticServices, BindingTrace trace) {
|
||||
|
||||
this.typeInferrer = new JetTypeInferrer(JetFlowInformationProvider.THROW_EXCEPTION, semanticServices);
|
||||
this.trace = trace;
|
||||
}
|
||||
|
||||
@@ -30,15 +36,19 @@ public class AnnotationResolver {
|
||||
public List<AnnotationDescriptor> resolveAnnotations(@NotNull JetScope scope, @NotNull List<JetAnnotationEntry> annotationEntryElements) {
|
||||
if (annotationEntryElements.isEmpty()) return Collections.emptyList();
|
||||
List<AnnotationDescriptor> result = Lists.newArrayList();
|
||||
// for (JetAnnotationEntry entryElement : annotationEntryElements) {
|
||||
// JetType jetType = typeInferrer.checkTypeInitializerCall(scope, entryElement.getTypeReference(), entryElement);
|
||||
// AnnotationDescriptor descriptor = new AnnotationDescriptor();
|
||||
// descriptor.setAnnotationType(jetType);
|
||||
// result.add(descriptor);
|
||||
// }
|
||||
for (JetAnnotationEntry entryElement : annotationEntryElements) {
|
||||
AnnotationDescriptor descriptor = new AnnotationDescriptor();
|
||||
resolveAnnotationStub(scope, entryElement, descriptor);
|
||||
result.add(descriptor);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void resolveAnnotationStub(@NotNull JetScope scope, @NotNull JetAnnotationEntry entryElement, @NotNull AnnotationDescriptor descriptor) {
|
||||
JetType jetType = typeInferrer.getCallResolver().resolveCall(trace, scope, null, entryElement, NO_EXPECTED_TYPE);
|
||||
descriptor.setAnnotationType(jetType == null ? ErrorUtils.createErrorType("Unresolved annotation type") : jetType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<AnnotationDescriptor> resolveAnnotations(@NotNull JetScope scope, @Nullable JetModifierList modifierList) {
|
||||
if (modifierList == null) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.JetDiagnostic;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
@@ -112,5 +113,6 @@ public interface BindingContext {
|
||||
|
||||
Collection<JetDiagnostic> getDiagnostics();
|
||||
|
||||
@Nullable
|
||||
<K, V> V get(ReadOnlySlice<K, V> slice, K key);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.ErrorHandler;
|
||||
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
|
||||
import org.jetbrains.jet.util.slicedmap.WritableSlice;
|
||||
@@ -20,5 +21,6 @@ public interface BindingTrace {
|
||||
// Writes TRUE for a boolean value
|
||||
<K> void record(WritableSlice<K, Boolean> slice, K key);
|
||||
|
||||
@Nullable
|
||||
<K, V> V get(ReadOnlySlice<K, V> slice, K key);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.jetbrains.jet.util.slicedmap.WritableSlice;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.ANNOTATION;
|
||||
import static org.jetbrains.jet.lang.types.JetTypeInferrer.NO_EXPECTED_TYPE;
|
||||
|
||||
/**
|
||||
@@ -40,6 +41,7 @@ public class TopDownAnalyzer {
|
||||
private final BindingTrace trace;
|
||||
private final BindingTraceAdapter traceForConstructors;
|
||||
private final BindingTraceAdapter traceForMembers;
|
||||
private final AnnotationResolver annotationResolver;
|
||||
|
||||
public TopDownAnalyzer(JetSemanticServices semanticServices, @NotNull BindingTrace bindingTrace) {
|
||||
this.semanticServices = semanticServices;
|
||||
@@ -73,6 +75,8 @@ public class TopDownAnalyzer {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.annotationResolver = new AnnotationResolver(semanticServices, trace);
|
||||
}
|
||||
|
||||
public void processObject(@NotNull JetScope outerScope, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetObjectDeclaration object) {
|
||||
@@ -117,7 +121,11 @@ public class TopDownAnalyzer {
|
||||
resolveTypesInClassHeaders(); // Generic bounds and types in supertype lists (no expressions or constructor resolution)
|
||||
checkGenericBoundsInClassHeaders(); // For the types resolved so far
|
||||
|
||||
resolveFunctionAndPropertyHeaders(); // Constructor headers are resolved as well
|
||||
resolveConstructorHeaders();
|
||||
|
||||
resolveAnnotationStubsOnClassesAndConstructors();
|
||||
|
||||
resolveFunctionAndPropertyHeaders();
|
||||
|
||||
resolveBehaviorDeclarationBodies();
|
||||
}
|
||||
@@ -372,6 +380,35 @@ public class TopDownAnalyzer {
|
||||
}
|
||||
}
|
||||
|
||||
private void resolveConstructorHeaders() {
|
||||
for (Map.Entry<JetClass, MutableClassDescriptor> entry : classes.entrySet()) {
|
||||
JetClass jetClass = entry.getKey();
|
||||
MutableClassDescriptor classDescriptor = entry.getValue();
|
||||
|
||||
processPrimaryConstructor(classDescriptor, jetClass);
|
||||
for (JetConstructor jetConstructor : jetClass.getSecondaryConstructors()) {
|
||||
processSecondaryConstructor(classDescriptor, jetConstructor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void resolveAnnotationStubsOnClassesAndConstructors() {
|
||||
for (Map.Entry<JetClass, MutableClassDescriptor> entry : classes.entrySet()) {
|
||||
JetClass jetClass = entry.getKey();
|
||||
MutableClassDescriptor mutableClassDescriptor = entry.getValue();
|
||||
|
||||
JetModifierList modifierList = jetClass.getModifierList();
|
||||
if (modifierList != null) {
|
||||
List<JetAnnotationEntry> annotationEntries = modifierList.getAnnotationEntries();
|
||||
for (JetAnnotationEntry annotationEntry : annotationEntries) {
|
||||
AnnotationDescriptor annotationDescriptor = trace.get(ANNOTATION, annotationEntry);
|
||||
annotationResolver.resolveAnnotationStub(mutableClassDescriptor.getScopeForSupertypeResolution(), annotationEntry, annotationDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resolveFunctionAndPropertyHeaders() {
|
||||
for (Map.Entry<JetNamespace, WritableScope> entry : namespaceScopes.entrySet()) {
|
||||
JetNamespace namespace = entry.getKey();
|
||||
@@ -385,10 +422,10 @@ public class TopDownAnalyzer {
|
||||
MutableClassDescriptor classDescriptor = entry.getValue();
|
||||
|
||||
resolveFunctionAndPropertyHeaders(jetClass.getDeclarations(), classDescriptor.getScopeForMemberResolution(), classDescriptor);
|
||||
processPrimaryConstructor(classDescriptor, jetClass);
|
||||
for (JetConstructor jetConstructor : jetClass.getSecondaryConstructors()) {
|
||||
processSecondaryConstructor(classDescriptor, jetConstructor);
|
||||
}
|
||||
// processPrimaryConstructor(classDescriptor, jetClass);
|
||||
// for (JetConstructor jetConstructor : jetClass.getSecondaryConstructors()) {
|
||||
// processSecondaryConstructor(classDescriptor, jetConstructor);
|
||||
// }
|
||||
}
|
||||
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : objects.entrySet()) {
|
||||
JetObjectDeclaration object = entry.getKey();
|
||||
|
||||
@@ -98,49 +98,54 @@ public class CallResolver {
|
||||
|
||||
prioritizedTasks = FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(scope, receiverType, call, name);
|
||||
}
|
||||
else if (calleeExpression instanceof JetConstructorCalleeExpression) {
|
||||
assert receiverType == null;
|
||||
else {
|
||||
JetValueArgumentList valueArgumentList = call.getValueArgumentList();
|
||||
ASTNode reportAbsenceOn = valueArgumentList == null ? call.getNode() : valueArgumentList.getNode();
|
||||
if (calleeExpression instanceof JetConstructorCalleeExpression) {
|
||||
assert receiverType == null;
|
||||
|
||||
prioritizedTasks = Lists.newArrayList();
|
||||
prioritizedTasks = Lists.newArrayList();
|
||||
|
||||
JetConstructorCalleeExpression expression = (JetConstructorCalleeExpression) calleeExpression;
|
||||
functionReference = expression.getConstructorReferenceExpression();
|
||||
if (functionReference == null) {
|
||||
return checkArgumentTypesAndFail(trace, scope, call); // No type there
|
||||
}
|
||||
JetTypeReference typeReference = expression.getTypeReference();
|
||||
assert typeReference != null;
|
||||
JetType constructedType = new TypeResolver(semanticServices, trace, true).resolveType(scope, typeReference);
|
||||
DeclarationDescriptor declarationDescriptor = constructedType.getConstructor().getDeclarationDescriptor();
|
||||
if (declarationDescriptor instanceof ClassDescriptor) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
|
||||
Set<FunctionDescriptor> constructors = classDescriptor.getConstructors().getFunctionDescriptors();
|
||||
if (constructors.isEmpty()) {
|
||||
trace.getErrorHandler().genericError(call.getValueArgumentList().getNode(), "This class does not have a constructor");
|
||||
JetConstructorCalleeExpression expression = (JetConstructorCalleeExpression) calleeExpression;
|
||||
functionReference = expression.getConstructorReferenceExpression();
|
||||
if (functionReference == null) {
|
||||
return checkArgumentTypesAndFail(trace, scope, call); // No type there
|
||||
}
|
||||
JetTypeReference typeReference = expression.getTypeReference();
|
||||
assert typeReference != null;
|
||||
JetType constructedType = new TypeResolver(semanticServices, trace, true).resolveType(scope, typeReference);
|
||||
DeclarationDescriptor declarationDescriptor = constructedType.getConstructor().getDeclarationDescriptor();
|
||||
if (declarationDescriptor instanceof ClassDescriptor) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
|
||||
Set<FunctionDescriptor> constructors = classDescriptor.getConstructors().getFunctionDescriptors();
|
||||
if (constructors.isEmpty()) {
|
||||
trace.getErrorHandler().genericError(reportAbsenceOn, "This class does not have a constructor");
|
||||
return checkArgumentTypesAndFail(trace, scope, call);
|
||||
}
|
||||
prioritizedTasks.add(new ResolutionTask<FunctionDescriptor>(constructors, null, call));
|
||||
}
|
||||
else {
|
||||
trace.getErrorHandler().genericError(calleeExpression.getNode(), "Not a class");
|
||||
return checkArgumentTypesAndFail(trace, scope, call);
|
||||
}
|
||||
prioritizedTasks.add(new ResolutionTask<FunctionDescriptor>(constructors, null, call));
|
||||
}
|
||||
else if (calleeExpression instanceof JetThisReferenceExpression) {
|
||||
functionReference = (JetThisReferenceExpression) calleeExpression;
|
||||
DeclarationDescriptor containingDeclaration = scope.getContainingDeclaration();
|
||||
assert containingDeclaration instanceof ClassDescriptor;
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
|
||||
|
||||
|
||||
Set<FunctionDescriptor> constructors = classDescriptor.getConstructors().getFunctionDescriptors();
|
||||
if (constructors.isEmpty()) {
|
||||
trace.getErrorHandler().genericError(reportAbsenceOn, "This class does not have a constructor");
|
||||
return checkArgumentTypesAndFail(trace, scope, call);
|
||||
}
|
||||
prioritizedTasks = Collections.singletonList(new ResolutionTask<FunctionDescriptor>(constructors, null, call));
|
||||
}
|
||||
else {
|
||||
trace.getErrorHandler().genericError(calleeExpression.getNode(), "Not a class");
|
||||
return checkArgumentTypesAndFail(trace, scope, call);
|
||||
throw new UnsupportedOperationException("Type argument inference not implemented for " + call.getText());
|
||||
}
|
||||
} else if (calleeExpression instanceof JetThisReferenceExpression) {
|
||||
functionReference = (JetThisReferenceExpression) calleeExpression;
|
||||
DeclarationDescriptor containingDeclaration = scope.getContainingDeclaration();
|
||||
assert containingDeclaration instanceof ClassDescriptor;
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
|
||||
|
||||
|
||||
Set<FunctionDescriptor> constructors = classDescriptor.getConstructors().getFunctionDescriptors();
|
||||
if (constructors.isEmpty()) {
|
||||
trace.getErrorHandler().genericError(call.getValueArgumentList().getNode(), "This class does not have a constructor");
|
||||
return checkArgumentTypesAndFail(trace, scope, call);
|
||||
}
|
||||
prioritizedTasks = Collections.singletonList(new ResolutionTask<FunctionDescriptor>(constructors, null, call));
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Type argument inference not implemented for " + call.getText());
|
||||
}
|
||||
|
||||
return resolveCallToDescriptor(trace, scope, call, call.getNode(), expectedType, prioritizedTasks, functionReference);
|
||||
|
||||
@@ -170,6 +170,10 @@ public class JetTypeInferrer {
|
||||
return new Services(trace);
|
||||
}
|
||||
|
||||
public CallResolver getCallResolver() {
|
||||
return callResolver;
|
||||
}
|
||||
|
||||
public class Services {
|
||||
private final BindingTrace trace;
|
||||
private final CompileTimeConstantResolver compileTimeConstantResolver;
|
||||
|
||||
Reference in New Issue
Block a user