KT-274 Add Enumeration.iterator () method in global namespace

Looking up iterator() via generic extensions' too
This commit is contained in:
Andrey Breslav
2012-02-03 14:57:16 +04:00
parent 75f1f06862
commit fba7829ab8
4 changed files with 52 additions and 8 deletions
@@ -6,6 +6,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFileFactory; import com.intellij.psi.PsiFileFactory;
import com.intellij.util.LocalTimeCounter; import com.intellij.util.LocalTimeCounter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lexer.JetKeywordToken; import org.jetbrains.jet.lexer.JetKeywordToken;
import org.jetbrains.jet.plugin.JetFileType; import org.jetbrains.jet.plugin.JetFileType;
@@ -54,11 +55,15 @@ public class JetPsiFactory {
return (JetFile) PsiFileFactory.getInstance(project).createFileFromText(fileName, JetFileType.INSTANCE, text, LocalTimeCounter.currentTime(), true); return (JetFile) PsiFileFactory.getInstance(project).createFileFromText(fileName, JetFileType.INSTANCE, text, LocalTimeCounter.currentTime(), true);
} }
public static JetProperty createProperty(Project project, String name, String type, boolean isVar) { public static JetProperty createProperty(Project project, String name, String type, boolean isVar, @Nullable String initializer) {
String text = (isVar ? "var " : "val ") + name + (type != null ? ":" + type : ""); String text = (isVar ? "var " : "val ") + name + (type != null ? ":" + type : "") + (initializer == null ? "" : " = " + initializer);
return createProperty(project, text); return createProperty(project, text);
} }
public static JetProperty createProperty(Project project, String name, String type, boolean isVar) {
return createProperty(project, name, type, isVar, null);
}
public static JetProperty createProperty(Project project, String text) { public static JetProperty createProperty(Project project, String text) {
return createDeclaration(project, text, JetProperty.class); return createDeclaration(project, text, JetProperty.class);
} }
@@ -76,6 +81,10 @@ public class JetPsiFactory {
return createProperty(project, name, null, false).getNameIdentifier(); return createProperty(project, name, null, false).getNameIdentifier();
} }
public static JetSimpleNameExpression createSimpleName(Project project, String name) {
return (JetSimpleNameExpression) createProperty(project, name, null, false, name).getInitializer();
}
public static JetNamedFunction createFunction(Project project, String funDecl) { public static JetNamedFunction createFunction(Project project, String funDecl) {
return createDeclaration(project, funDecl, JetNamedFunction.class); return createDeclaration(project, funDecl, JetNamedFunction.class);
} }
@@ -52,6 +52,8 @@ public class JetStandardLibrary {
// return standardLibrary; // return standardLibrary;
} }
private final Project project;
private JetScope libraryScope; private JetScope libraryScope;
private ClassDescriptor numberClass; private ClassDescriptor numberClass;
@@ -90,6 +92,8 @@ public class JetStandardLibrary {
private Map<JetType, JetType> jetArrayTypeToPrimitiveJetType; private Map<JetType, JetType> jetArrayTypeToPrimitiveJetType;
private JetStandardLibrary(@NotNull Project project) { private JetStandardLibrary(@NotNull Project project) {
this.project = project;
// TODO : review // TODO : review
List<String> libraryFiles = Arrays.asList( List<String> libraryFiles = Arrays.asList(
"Library.jet", "Library.jet",
@@ -129,6 +133,11 @@ public class JetStandardLibrary {
} }
} }
@NotNull
public Project getProject() {
return project;
}
public JetScope getLibraryScope() { public JetScope getLibraryScope() {
initStdClasses(); initStdClasses();
return libraryScope; return libraryScope;
@@ -8,9 +8,8 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.calls.CallMaker;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
@@ -265,7 +264,20 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
@Nullable @Nullable
private JetType checkIterableConvention(@NotNull ExpressionReceiver loopRange, ExpressionTypingContext context) { private JetType checkIterableConvention(@NotNull ExpressionReceiver loopRange, ExpressionTypingContext context) {
JetExpression loopRangeExpression = loopRange.getExpression(); JetExpression loopRangeExpression = loopRange.getExpression();
OverloadResolutionResults<FunctionDescriptor> iteratorResolutionResults = context.resolveExactSignature(loopRange, "iterator", Collections.<JetType>emptyList());
// Make a fake call loopRange.iterator(), and try to resolve it
String iterator = "iterator";
OverloadResolutionResults<FunctionDescriptor> iteratorResolutionResults = resolveFakeCall(loopRange, context, iterator);
// We allow the loop range to be null (nothing happens), so we make the receiver type non-null
if (!iteratorResolutionResults.isSuccess()) {
ExpressionReceiver nonNullReceiver = new ExpressionReceiver(loopRange.getExpression(), TypeUtils.makeNotNullable(loopRange.getType()));
OverloadResolutionResults<FunctionDescriptor> iteratorResolutionResultsWithNonNullReceiver = resolveFakeCall(nonNullReceiver, context, iterator);
if (iteratorResolutionResultsWithNonNullReceiver.isSuccess()) {
iteratorResolutionResults = iteratorResolutionResultsWithNonNullReceiver;
}
}
if (iteratorResolutionResults.isSuccess()) { if (iteratorResolutionResults.isSuccess()) {
FunctionDescriptor iteratorFunction = iteratorResolutionResults.getResultingCall().getResultingDescriptor(); FunctionDescriptor iteratorFunction = iteratorResolutionResults.getResultingCall().getResultingDescriptor();
@@ -314,6 +326,13 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
return null; return null;
} }
private OverloadResolutionResults<FunctionDescriptor> resolveFakeCall(ExpressionReceiver receiver, ExpressionTypingContext context, String name) {
JetReferenceExpression fake = JetPsiFactory.createSimpleName(context.getProject(), "fake");
BindingTrace fakeTrace = new BindingTraceContext();
Call call = CallMaker.makeCall(fake, receiver, null, fake, Collections.<ValueArgument>emptyList());
return context.replaceBindingTrace(fakeTrace).resolveCallWithGivenName(call, fake, name);
}
@Nullable @Nullable
private FunctionDescriptor checkHasNextFunctionSupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) { private FunctionDescriptor checkHasNextFunctionSupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) {
OverloadResolutionResults<FunctionDescriptor> hasNextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "hasNext", Collections.<JetType>emptyList()); OverloadResolutionResults<FunctionDescriptor> hasNextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "hasNext", Collections.<JetType>emptyList());
@@ -1,17 +1,19 @@
package org.jetbrains.jet.lang.types.expressions; package org.jetbrains.jet.lang.types.expressions;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
import com.intellij.openapi.project.Project;
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.JetSemanticServices; import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.TypeResolver; import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.resolve.calls.*; import org.jetbrains.jet.lang.resolve.calls.CallMaker;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
@@ -198,4 +200,9 @@ import java.util.Map;
public OverloadResolutionResults<FunctionDescriptor> resolveExactSignature(@NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List<JetType> parameterTypes) { public OverloadResolutionResults<FunctionDescriptor> resolveExactSignature(@NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List<JetType> parameterTypes) {
return getCallResolver().resolveExactSignature(scope, receiver, name, parameterTypes); return getCallResolver().resolveExactSignature(scope, receiver, name, parameterTypes);
} }
@NotNull
public Project getProject() {
return semanticServices.getStandardLibrary().getProject();
}
} }