Cosmetics + Debug info

This commit is contained in:
Andrey Breslav
2011-06-18 21:04:10 +04:00
parent 88f4beb85c
commit f1d00f3f59
19 changed files with 344 additions and 148 deletions
@@ -66,6 +66,10 @@ public class ErrorHandlerWithRegions extends ErrorHandler {
return new DiagnosticsRegion(currentWorker);
}
public void close() {
assert workers.isEmpty() : "Open regions remain: " + workers;
}
private void setWorker() {
worker = workers.isEmpty() ? parent : workers.peek();
}
@@ -98,7 +98,7 @@ public class FunctionDescriptorUtil {
@NotNull
public static JetScope getFunctionInnerScope(@NotNull JetScope outerScope, @NotNull FunctionDescriptor descriptor, @NotNull BindingTrace trace) {
WritableScope parameterScope = new WritableScopeImpl(outerScope, descriptor, trace.getErrorHandler());
WritableScope parameterScope = new WritableScopeImpl(outerScope, descriptor, trace.getErrorHandler()).setDebugName("Function inner scope");
JetType receiverType = descriptor.getReceiverType();
if (receiverType != null) {
parameterScope.setThisType(receiverType);
@@ -1,6 +1,7 @@
package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lexer.JetTokens;
@@ -8,7 +9,7 @@ import org.jetbrains.jet.lexer.JetTokens;
/**
* @author max
*/
public class JetArgument extends JetElement {
public class JetArgument extends JetElement implements ValueArgumentPsi {
public JetArgument(@NotNull ASTNode node) {
super(node);
}
@@ -22,6 +23,11 @@ public class JetArgument extends JetElement {
return findChildByClass(JetExpression.class);
}
@Override
public PsiElement asElement() {
return this;
}
@Nullable
public String getArgumentName() {
ASTNode firstChildNode = getNode().getFirstChildNode();
@@ -0,0 +1,48 @@
package org.jetbrains.jet.lang.psi;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.Nullable;
/**
* @author abreslav
*/
public interface ValueArgumentPsi {
class ArgumentExpressionWrapper implements ValueArgumentPsi {
private final JetExpression expression;
public ArgumentExpressionWrapper(JetExpression expression) {
this.expression = expression;
}
@Override
public PsiElement asElement() {
return expression;
}
@Override
public String getArgumentName() {
return null;
}
@Override
public boolean isNamed() {
return false;
}
@Override
public JetExpression getArgumentExpression() {
return expression;
}
}
PsiElement asElement();
@Nullable
String getArgumentName();
boolean isNamed();
@Nullable
public JetExpression getArgumentExpression();
}
@@ -71,7 +71,7 @@ public class AnalyzingUtils {
JetScope libraryScope = semanticServices.getStandardLibrary().getLibraryScope();
ModuleDescriptor owner = new ModuleDescriptor("<module>");
final WritableScope scope = new WritableScopeImpl(libraryScope, owner, bindingTraceContext.getErrorHandler());
final WritableScope scope = new WritableScopeImpl(libraryScope, owner, bindingTraceContext.getErrorHandler()).setDebugName("Root scope in analyzeNamespace");
// scope.importScope(javaSemanticServices.getDescriptorResolver().resolveNamespace("").getMemberScope());
// scope.importScope(javaSemanticServices.getDescriptorResolver().resolveNamespace("java.lang").getMemberScope());
scope.importScope(new JavaPackageScope("", null, javaSemanticServices));
@@ -33,8 +33,6 @@ public interface BindingTrace {
void removeStatementRecord(@NotNull JetElement statement);
void removeReferenceResolution(@NotNull JetReferenceExpression referenceExpression);
void requireBackingField(@NotNull PropertyDescriptor propertyDescriptor);
void recordAutoCast(@NotNull JetExpression expression, @NotNull JetType type);
@@ -52,10 +52,6 @@ public class BindingTraceAdapter implements BindingTrace {
originalTrace.recordBlock(expression);
}
public void removeReferenceResolution(@NotNull JetReferenceExpression referenceExpression) {
originalTrace.removeReferenceResolution(referenceExpression);
}
@Override
public void recordStatement(@NotNull JetElement statement) {
originalTrace.recordStatement(statement);
@@ -28,17 +28,56 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
private final Map<PsiElement, ConstructorDescriptor> constructorDeclarationsToDescriptors = new HashMap<PsiElement, ConstructorDescriptor>();
private final Map<PsiElement, NamespaceDescriptor> namespaceDeclarationsToDescriptors = Maps.newHashMap();
private final Map<PsiElement, PropertyDescriptor> primaryConstructorParameterDeclarationsToPropertyDescriptors = Maps.newHashMap();
private final Map<JetExpression, JetType> autoCasts = Maps.newHashMap();
private final Map<JetExpression, JetScope> resolutionScopes = Maps.newHashMap();
private final Set<JetFunctionLiteralExpression> blocks = new HashSet<JetFunctionLiteralExpression>();
private final Set<JetElement> statements = new HashSet<JetElement>();
private final Set<PropertyDescriptor> backingFieldRequired = new HashSet<PropertyDescriptor>();
private final Set<JetExpression> processed = Sets.newHashSet();
private final Map<JetExpression, JetType> autoCasts = Maps.newHashMap();
private final List<JetDiagnostic> diagnostics = Lists.newArrayList();
private final ErrorHandlerWithRegions errorHandler = new ErrorHandlerWithRegions(new CollectingErrorHandler(diagnostics));
private Map<JetExpression, JetScope> resolutionScopes = Maps.newHashMap();
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private final ErrorHandlerWithRegions errorHandler = new ErrorHandlerWithRegions(new CollectingErrorHandler(diagnostics));
public BindingTraceContext() {
}
public void destructiveMerge(BindingTraceContext other) {
safePutAll(expressionTypes, other.expressionTypes);
resolutionResults.putAll(other.resolutionResults);
safePutAll(labelResolutionResults, other.labelResolutionResults);
safePutAll(types, other.types);
safePutAll(descriptorToDeclarations, other.descriptorToDeclarations);
safePutAll(declarationsToDescriptors, other.declarationsToDescriptors);
safePutAll(constructorDeclarationsToDescriptors, other.constructorDeclarationsToDescriptors);
safePutAll(namespaceDeclarationsToDescriptors, other.namespaceDeclarationsToDescriptors);
safePutAll(primaryConstructorParameterDeclarationsToPropertyDescriptors, other.primaryConstructorParameterDeclarationsToPropertyDescriptors);
safePutAll(autoCasts, other.autoCasts);
safePutAll(resolutionScopes, other.resolutionScopes);
blocks.addAll(other.blocks);
statements.addAll(other.statements);
backingFieldRequired.addAll(other.backingFieldRequired);
processed.addAll(other.processed);
diagnostics.addAll(other.diagnostics);
}
private <K, V> void safePutAll(Map<K, V> my, Map<K, V> other) {
assert keySetIntersection(my, other).isEmpty() : keySetIntersection(my, other);
my.putAll(other);
}
private <K, V> HashSet<K> keySetIntersection(Map<K, V> my, Map<K, V> other) {
HashSet<K> keySet = Sets.newHashSet(my.keySet());
keySet.retainAll(other.keySet());
return keySet;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@NotNull
public ErrorHandlerWithRegions getErrorHandler() {
@@ -60,11 +99,6 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
safePut(labelResolutionResults, expression, element);
}
@Override
public void removeReferenceResolution(@NotNull JetReferenceExpression referenceExpression) {
resolutionResults.remove(referenceExpression);
}
@Override
public void recordTypeResolution(@NotNull JetTypeReference typeReference, @NotNull JetType type) {
safePut(types, typeReference, type);
@@ -101,8 +135,7 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
private <K, V> void safePut(Map<K, V> map, K key, V value) {
V oldValue = map.put(key, value);
// TODO:
assert oldValue == null || oldValue == value : key + ": " + oldValue + " and " + value;
assert oldValue == null || oldValue == value : (key instanceof PsiElement ? key.toString() + " \"" + ((PsiElement) key).getText() + "\"" : key.toString()) + " -> " + oldValue + " and " + value;
}
@Override
@@ -127,7 +160,7 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
@Override
public void recordResolutionScope(@NotNull JetExpression expression, @NotNull JetScope scope) {
resolutionScopes.put(expression, scope);
safePut(resolutionScopes, expression, scope);
}
@Override
@@ -164,7 +164,7 @@ public class ClassDescriptorResolver {
AnnotationResolver.INSTANCE.resolveAnnotations(function.getModifierList()),
JetPsiUtil.safeName(function.getName())
);
WritableScope innerScope = new WritableScopeImpl(scope, functionDescriptor, trace.getErrorHandler());
WritableScope innerScope = new WritableScopeImpl(scope, functionDescriptor, trace.getErrorHandler()).setDebugName("Function descriptor header scope");
innerScope.addLabeledDeclaration(functionDescriptor);
List<TypeParameterDescriptor> typeParameterDescriptors = resolveTypeParameters(functionDescriptor, innerScope, function.getTypeParameters());
@@ -474,7 +474,7 @@ public class ClassDescriptorResolver {
typeParameterDescriptors = Collections.emptyList();
}
else {
WritableScope writableScope = new WritableScopeImpl(scope, containingDeclaration, trace.getErrorHandler());
WritableScope writableScope = new WritableScopeImpl(scope, containingDeclaration, trace.getErrorHandler()).setDebugName("Scope with type parameters of a property");
typeParameterDescriptors = resolveTypeParameters(containingDeclaration, writableScope, typeParameters);
resolveGenericBounds(property, writableScope, typeParameterDescriptors);
scopeWithTypeParameters = writableScope;
@@ -525,7 +525,7 @@ public class ClassDescriptorResolver {
LazyValue<JetType> lazyValue = new LazyValue<JetType>() {
@Override
protected JetType compute() {
return semanticServices.getTypeInferrer(trace, JetFlowInformationProvider.THROW_EXCEPTION).safeGetType(scope, initializer, false, null); // TODO
return semanticServices.getTypeInferrer(trace, JetFlowInformationProvider.THROW_EXCEPTION).safeGetType(scope, initializer, false, JetTypeInferrer.NO_EXPECTED_TYPE);
}
};
if (allowDeferred) {
@@ -646,7 +646,7 @@ public class ClassDescriptorResolver {
typeParameters,
resolveValueParameters(
constructorDescriptor,
new WritableScopeImpl(scope, classDescriptor, trace.getErrorHandler()),
new WritableScopeImpl(scope, classDescriptor, trace.getErrorHandler()).setDebugName("Scope with value parameters of a constructor"),
valueParameters));
}
@@ -128,6 +128,8 @@ public class TopDownAnalyzer {
resolveFunctionAndPropertyHeaders(); // Constructor headers are resolved as well
resolveBehaviorDeclarationBodies();
trace.getErrorHandler().close();
}
private void collectNamespacesAndClassifiers(
@@ -150,7 +152,7 @@ public class TopDownAnalyzer {
Collections.<Annotation>emptyList(), // TODO
name
);
namespaceDescriptor.initialize(new WritableScopeImpl(JetScope.EMPTY, namespaceDescriptor, trace.getErrorHandler()));
namespaceDescriptor.initialize(new WritableScopeImpl(JetScope.EMPTY, namespaceDescriptor, trace.getErrorHandler()).setDebugName("Namespace member scope"));
owner.addNamespace(namespaceDescriptor);
trace.recordDeclarationResolution(namespace, namespaceDescriptor);
}
@@ -570,7 +572,7 @@ public class TopDownAnalyzer {
JetExpression delegateExpression = specifier.getDelegateExpression();
if (delegateExpression != null) {
JetScope scope = scopeForConstructor == null ? descriptor.getScopeForMemberResolution() : scopeForConstructor;
JetType type = typeInferrer.getType(scope, delegateExpression, false, null);
JetType type = typeInferrer.getType(scope, delegateExpression, false, JetTypeInferrer.NO_EXPECTED_TYPE);
JetType supertype = trace.getBindingContext().resolveTypeReference(specifier.getTypeReference());
if (type != null && !semanticServices.getTypeChecker().isSubtypeOf(type, supertype)) { // TODO : Convertible?
trace.getErrorHandler().typeMismatch(delegateExpression, supertype, type);
@@ -583,7 +585,7 @@ public class TopDownAnalyzer {
JetTypeReference typeReference = call.getTypeReference();
if (typeReference != null) {
if (descriptor.getUnsubstitutedPrimaryConstructor() != null) {
typeInferrer.checkConstructorCall(scopeForConstructor, typeReference, call);
typeInferrer.checkTypeInitializerCall(scopeForConstructor, typeReference, call);
}
else {
JetArgumentList valueArgumentList = call.getValueArgumentList();
@@ -642,7 +644,7 @@ public class TopDownAnalyzer {
final JetScope scopeForConstructor = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true);
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(traceForConstructors, JetFlowInformationProvider.NONE); // TODO : flow
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), true, null);
typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), true, JetTypeInferrer.NO_EXPECTED_TYPE);
}
}
else {
@@ -684,7 +686,7 @@ public class TopDownAnalyzer {
public void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call) {
JetTypeReference typeReference = call.getTypeReference();
if (typeReference != null) {
typeInferrerForInitializers.checkConstructorCall(functionInnerScope, typeReference, call);
typeInferrerForInitializers.checkTypeInitializerCall(functionInnerScope, typeReference, call);
}
}
@@ -734,7 +736,7 @@ public class TopDownAnalyzer {
@NotNull
private JetScope getInnerScopeForConstructor(@NotNull ConstructorDescriptor descriptor, @NotNull JetScope declaringScope, boolean primary) {
WritableScope constructorScope = new WritableScopeImpl(declaringScope, declaringScope.getContainingDeclaration(), trace.getErrorHandler());
WritableScope constructorScope = new WritableScopeImpl(declaringScope, declaringScope.getContainingDeclaration(), trace.getErrorHandler()).setDebugName("Inner scope for constructor");
for (PropertyDescriptor propertyDescriptor : ((MutableClassDescriptor) descriptor.getContainingDeclaration()).getProperties()) {
constructorScope.addPropertyDescriptorByFieldName("$" + propertyDescriptor.getName(), propertyDescriptor);
}
@@ -802,7 +804,7 @@ public class TopDownAnalyzer {
}
private JetScope getPropertyDeclarationInnerScope(@NotNull JetScope outerScope, @NotNull PropertyDescriptor propertyDescriptor) {
WritableScopeImpl result = new WritableScopeImpl(outerScope, propertyDescriptor, trace.getErrorHandler());
WritableScopeImpl result = new WritableScopeImpl(outerScope, propertyDescriptor, trace.getErrorHandler()).setDebugName("Property declaration inner scope");
for (TypeParameterDescriptor typeParameterDescriptor : propertyDescriptor.getTypeParemeters()) {
result.addTypeParameterDescriptor(typeParameterDescriptor);
}
@@ -816,7 +818,7 @@ public class TopDownAnalyzer {
private void resolvePropertyAccessors(JetProperty property, PropertyDescriptor propertyDescriptor, JetScope declaringScope) {
BindingTraceAdapter fieldAccessTrackingTrace = createFieldTrackingTrace(propertyDescriptor);
WritableScope accessorScope = new WritableScopeImpl(getPropertyDeclarationInnerScope(declaringScope, propertyDescriptor), declaringScope.getContainingDeclaration(), trace.getErrorHandler());
WritableScope accessorScope = new WritableScopeImpl(getPropertyDeclarationInnerScope(declaringScope, propertyDescriptor), declaringScope.getContainingDeclaration(), trace.getErrorHandler()).setDebugName("Accessor scope");
accessorScope.addPropertyDescriptorByFieldName("$" + propertyDescriptor.getName(), propertyDescriptor);
JetPropertyAccessor getter = property.getGetter();
@@ -858,7 +860,7 @@ public class TopDownAnalyzer {
private void resolvePropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer, JetScope scope) {
JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(property, initializer); // TODO : flow JET-15
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(traceForConstructors, flowInformationProvider);
JetType type = typeInferrer.getType(getPropertyDeclarationInnerScope(scope, propertyDescriptor), initializer, false, null);
JetType type = typeInferrer.getType(getPropertyDeclarationInnerScope(scope, propertyDescriptor), initializer, false, JetTypeInferrer.NO_EXPECTED_TYPE);
JetType expectedType;
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
@@ -908,4 +910,6 @@ public class TopDownAnalyzer {
assert functionDescriptor.getUnsubstitutedReturnType() != null;
}
}
@@ -326,4 +326,10 @@ public class WritableScopeImpl extends WritableScopeWithImports {
public boolean hasDeclaredItems() {
return variableClassOrNamespaceDescriptors != null && !variableClassOrNamespaceDescriptors.isEmpty();
}
@Override
public WritableScopeImpl setDebugName(@NotNull String debugName) {
super.setDebugName(debugName);
return this;
}
}
@@ -96,7 +96,7 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement
public void importClassifierAlias(@NotNull String importedClassifierName, @NotNull ClassifierDescriptor classifierDescriptor) {
if (currentIndividualImportScope == null) {
WritableScopeImpl writableScope = new WritableScopeImpl(JetScope.EMPTY, getContainingDeclaration(), ErrorHandler.DO_NOTHING);
WritableScopeImpl writableScope = new WritableScopeImpl(JetScope.EMPTY, getContainingDeclaration(), ErrorHandler.DO_NOTHING).setDebugName("Individual import scope");
importScope(writableScope);
currentIndividualImportScope = writableScope;
}
@@ -105,7 +105,7 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement
@Override
public String toString() {
return debugName + " for " + getContainingDeclaration();
return getClass().getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this)) + " " + debugName + " for " + getContainingDeclaration();
}
}
@@ -185,7 +185,7 @@ public class JetStandardClasses {
/*package*/ static final JetScope STANDARD_CLASSES;
static {
WritableScope writableScope = new WritableScopeImpl(JetScope.EMPTY, STANDARD_CLASSES_NAMESPACE, ErrorHandler.DO_NOTHING);
WritableScope writableScope = new WritableScopeImpl(JetScope.EMPTY, STANDARD_CLASSES_NAMESPACE, ErrorHandler.DO_NOTHING).setDebugName("JetStandardClasses.STANDARD_CLASSES");
STANDARD_CLASSES = writableScope;
writableScope.addClassifierAlias("Unit", getTuple(0));
@@ -75,7 +75,7 @@ public class JetStandardLibrary {
JetSemanticServices bootstrappingSemanticServices = JetSemanticServices.createSemanticServices(this);
BindingTraceContext bindingTraceContext = new BindingTraceContext();
TopDownAnalyzer bootstrappingTDA = new TopDownAnalyzer(bootstrappingSemanticServices, bindingTraceContext);
WritableScopeImpl writableScope = new WritableScopeImpl(JetStandardClasses.STANDARD_CLASSES, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, ErrorHandler.THROW_EXCEPTION);
WritableScopeImpl writableScope = new WritableScopeImpl(JetStandardClasses.STANDARD_CLASSES, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, ErrorHandler.THROW_EXCEPTION).setDebugName("Root bootstrap scope");
// this.libraryScope = bootstrappingTDA.process(JetStandardClasses.STANDARD_CLASSES, file.getRootNamespace().getDeclarations());
// bootstrappingTDA.process(writableScope, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, file.getRootNamespace().getDeclarations());
bootstrappingTDA.processStandardLibraryNamespace(writableScope, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, file.getRootNamespace());
@@ -44,11 +44,13 @@ public final class JetTypeImpl extends AnnotatedImpl implements JetType {
classDescriptor.getMemberScope(Collections.<TypeProjection>emptyList()));
}
@NotNull
@Override
public TypeConstructor getConstructor() {
return constructor;
}
@NotNull
@Override
public List<TypeProjection> getArguments() {
return arguments;
@@ -55,47 +55,73 @@ public class JetTypeInferrer {
throw new UnsupportedOperationException(); // TODO
}
};
public static final JetType NO_EXPECTED_TYPE = new JetType() {
@NotNull
@Override
public TypeConstructor getConstructor() {
throw new UnsupportedOperationException(); // TODO
}
private static final Map<IElementType, String> unaryOperationNames = ImmutableMap.<IElementType, String>builder()
@NotNull
@Override
public List<TypeProjection> getArguments() {
throw new UnsupportedOperationException(); // TODO
}
@Override
public boolean isNullable() {
throw new UnsupportedOperationException(); // TODO
}
@NotNull
@Override
public JetScope getMemberScope() {
throw new UnsupportedOperationException(); // TODO
}
@Override
public List<Annotation> getAnnotations() {
throw new UnsupportedOperationException(); // TODO
}
};
private static final ImmutableMap<IElementType, String> unaryOperationNames = ImmutableMap.<IElementType, String>builder()
.put(JetTokens.PLUSPLUS, "inc")
.put(JetTokens.MINUSMINUS, "dec")
.put(JetTokens.PLUS, "plus")
.put(JetTokens.MINUS, "minus")
.put(JetTokens.EXCL, "not")
.build();
private static final Map<IElementType, String> binaryOperationNames = new HashMap<IElementType, String>();
private static final ImmutableMap<IElementType, String> binaryOperationNames = ImmutableMap.<IElementType, String>builder()
.put(JetTokens.MUL, "times")
.put(JetTokens.PLUS, "plus")
.put(JetTokens.MINUS, "minus")
.put(JetTokens.DIV, "div")
.put(JetTokens.PERC, "mod")
.put(JetTokens.ARROW, "arrow")
.put(JetTokens.RANGE, "rangeTo")
.build();
static {
binaryOperationNames.put(JetTokens.MUL, "times");
binaryOperationNames.put(JetTokens.PLUS, "plus");
binaryOperationNames.put(JetTokens.MINUS, "minus");
binaryOperationNames.put(JetTokens.DIV, "div");
binaryOperationNames.put(JetTokens.PERC, "mod");
binaryOperationNames.put(JetTokens.ARROW, "arrow");
binaryOperationNames.put(JetTokens.RANGE, "rangeTo");
}
private static final Set<IElementType> comparisonOperations = new HashSet<IElementType>(Arrays.asList(JetTokens.LT, JetTokens.GT, JetTokens.LTEQ, JetTokens.GTEQ));
private static final Set<IElementType> equalsOperations = new HashSet<IElementType>(Arrays.asList(JetTokens.EQEQ, JetTokens.EXCLEQ));
private static final Set<IElementType> comparisonOperations = Sets.<IElementType>newHashSet(JetTokens.LT, JetTokens.GT, JetTokens.LTEQ, JetTokens.GTEQ);
private static final Set<IElementType> equalsOperations = Sets.<IElementType>newHashSet(JetTokens.EQEQ, JetTokens.EXCLEQ);
private static final Set<IElementType> inOperations = new HashSet<IElementType>(Arrays.asList(JetTokens.IN_KEYWORD, JetTokens.NOT_IN));
public static final Map<IElementType, String> assignmentOperationNames = new HashMap<IElementType, String>();
private static final Set<IElementType> inOperations = Sets.<IElementType>newHashSet(JetTokens.IN_KEYWORD, JetTokens.NOT_IN);
public static final ImmutableMap<IElementType, String> assignmentOperationNames = ImmutableMap.<IElementType, String>builder()
.put(JetTokens.MULTEQ, "timesAssign")
.put(JetTokens.DIVEQ, "divAssign")
.put(JetTokens.PERCEQ, "modAssign")
.put(JetTokens.PLUSEQ, "plusAssign")
.put(JetTokens.MINUSEQ, "minusAssign")
.build();
static {
assignmentOperationNames.put(JetTokens.MULTEQ, "timesAssign");
assignmentOperationNames.put(JetTokens.DIVEQ, "divAssign");
assignmentOperationNames.put(JetTokens.PERCEQ, "modAssign");
assignmentOperationNames.put(JetTokens.PLUSEQ, "plusAssign");
assignmentOperationNames.put(JetTokens.MINUSEQ, "minusAssign");
}
private static final Map<IElementType, IElementType> assignmentOperationCounterparts = new HashMap<IElementType, IElementType>();
private static final ImmutableMap<IElementType, IElementType> assignmentOperationCounterparts = ImmutableMap.<IElementType, IElementType>builder()
.put(JetTokens.MULTEQ, JetTokens.MUL)
.put(JetTokens.DIVEQ, JetTokens.DIV)
.put(JetTokens.PERCEQ, JetTokens.PERC)
.put(JetTokens.PLUSEQ, JetTokens.PLUS)
.put(JetTokens.MINUSEQ, JetTokens.MINUS)
.build();
static {
assignmentOperationCounterparts.put(JetTokens.MULTEQ, JetTokens.MUL);
assignmentOperationCounterparts.put(JetTokens.DIVEQ, JetTokens.DIV);
assignmentOperationCounterparts.put(JetTokens.PERCEQ, JetTokens.PERC);
assignmentOperationCounterparts.put(JetTokens.PLUSEQ, JetTokens.PLUS);
assignmentOperationCounterparts.put(JetTokens.MINUSEQ, JetTokens.MINUS);
}
private final BindingTrace trace;
private final JetSemanticServices semanticServices;
private final TypeResolver typeResolver;
@@ -113,7 +139,7 @@ public class JetTypeInferrer {
}
@NotNull
public JetType safeGetType(@NotNull final JetScope scope, @NotNull JetExpression expression, boolean preferBlock, @Nullable JetType expectedType) {
public JetType safeGetType(@NotNull final JetScope scope, @NotNull JetExpression expression, boolean preferBlock, @NotNull JetType expectedType) {
JetType type = getType(scope, expression, preferBlock, expectedType);
if (type != null) {
return type;
@@ -122,12 +148,12 @@ public class JetTypeInferrer {
}
@Nullable
public JetType getType(@NotNull final JetScope scope, @NotNull JetExpression expression, boolean preferBlock, @Nullable JetType expectedType) {
public JetType getType(@NotNull final JetScope scope, @NotNull JetExpression expression, boolean preferBlock, @NotNull JetType expectedType) {
return new TypeInferrerVisitor(scope, preferBlock, DataFlowInfo.getEmpty(), expectedType, FORBIDDEN).getType(expression);
}
public JetType getTypeWithNamespaces(@NotNull final JetScope scope, @NotNull JetExpression expression, boolean preferBlock) {
return new TypeInferrerVisitorWithNamespaces(scope, preferBlock, DataFlowInfo.getEmpty(), null, null).getType(expression);
return new TypeInferrerVisitorWithNamespaces(scope, preferBlock, DataFlowInfo.getEmpty(), NO_EXPECTED_TYPE, null).getType(expression);
}
@Nullable
@@ -346,7 +372,7 @@ public class JetTypeInferrer {
public void checkFunctionReturnType(JetScope functionInnerScope, JetDeclarationWithBody function, FunctionDescriptor functionDescriptor, @Nullable final JetType expectedReturnType) {
JetExpression bodyExpression = function.getBodyExpression();
assert bodyExpression != null;
new TypeInferrerVisitor(functionInnerScope, function.hasBlockBody(), DataFlowInfo.getEmpty(), null, expectedReturnType).getType(bodyExpression);
new TypeInferrerVisitor(functionInnerScope, function.hasBlockBody(), DataFlowInfo.getEmpty(), NO_EXPECTED_TYPE, expectedReturnType).getType(bodyExpression);
List<JetElement> unreachableElements = Lists.newArrayList();
flowInformationProvider.collectUnreachableExpressions(function.asElement(), unreachableElements);
@@ -409,7 +435,7 @@ public class JetTypeInferrer {
JetExpression bodyExpression = function.getBodyExpression();
assert bodyExpression != null;
JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace);
new TypeInferrerVisitor(functionInnerScope, function.hasBlockBody(), DataFlowInfo.getEmpty(), null, FORBIDDEN).getType(bodyExpression);
new TypeInferrerVisitor(functionInnerScope, function.hasBlockBody(), DataFlowInfo.getEmpty(), NO_EXPECTED_TYPE, FORBIDDEN).getType(bodyExpression);
Collection<JetExpression> returnedExpressions = new ArrayList<JetExpression>();
Collection<JetElement> elementsReturningUnit = new ArrayList<JetElement>();
flowInformationProvider.collectReturnedInformation(function.asElement(), returnedExpressions, elementsReturningUnit);
@@ -434,7 +460,7 @@ public class JetTypeInferrer {
}
DeclarationDescriptor containingDescriptor = outerScope.getContainingDeclaration();
WritableScope scope = new WritableScopeImpl(outerScope, containingDescriptor, trace.getErrorHandler());
WritableScope scope = new WritableScopeImpl(outerScope, containingDescriptor, trace.getErrorHandler()).setDebugName("getBlockReturnedType");
return getBlockReturnedTypeWithWritableScope(scope, block, dataFlowInfo, extectedReturnType);
}
@@ -443,7 +469,7 @@ public class JetTypeInferrer {
return JetStandardClasses.getUnitType();
}
TypeInferrerVisitorWithWritableScope blockLevelVisitor = new TypeInferrerVisitorWithWritableScope(scope, true, dataFlowInfo, null, extectedReturnType);
TypeInferrerVisitorWithWritableScope blockLevelVisitor = new TypeInferrerVisitorWithWritableScope(scope, true, dataFlowInfo, NO_EXPECTED_TYPE, extectedReturnType);
JetType result = null;
for (JetElement statement : block) {
@@ -459,7 +485,7 @@ public class JetTypeInferrer {
// newScope = scope;
// }
if (newDataFlowInfo != dataFlowInfo) {// || newScope != scope) {
blockLevelVisitor = new TypeInferrerVisitorWithWritableScope(scope, true, newDataFlowInfo, null, extectedReturnType);
blockLevelVisitor = new TypeInferrerVisitorWithWritableScope(scope, true, newDataFlowInfo, NO_EXPECTED_TYPE, extectedReturnType);
}
else {
blockLevelVisitor.resetResult(); // TODO : maybe it's better to recreate the visitors with the same scope?
@@ -530,7 +556,7 @@ public class JetTypeInferrer {
List<JetType> valueArgumentTypes = new ArrayList<JetType>();
for (JetExpression valueArgument : positionedValueArguments) {
valueArgumentTypes.add(safeGetType(scope, valueArgument, false, null)); // TODO
valueArgumentTypes.add(safeGetType(scope, valueArgument, false, NO_EXPECTED_TYPE)); // TODO
}
OverloadResolutionResult resolutionResult = overloadDomain.getFunctionDescriptorForPositionedArguments(typeArguments, valueArgumentTypes);
@@ -564,7 +590,7 @@ public class JetTypeInferrer {
}
@Nullable
public JetType checkConstructorCall(JetScope scope, @NotNull JetTypeReference typeReference, @NotNull JetCall call) {
public JetType checkTypeInitializerCall(JetScope scope, @NotNull JetTypeReference typeReference, @NotNull JetCall call) {
JetTypeElement typeElement = typeReference.getTypeElement();
if (typeElement instanceof JetUserType) {
JetUserType userType = (JetUserType) typeElement;
@@ -677,6 +703,9 @@ public class JetTypeInferrer {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private class TypeInferrerVisitor extends JetVisitor {
// protected final BindingTrace trace;
protected final JetScope scope;
private final boolean preferBlock;
protected final DataFlowInfo dataFlowInfo;
@@ -684,17 +713,16 @@ public class JetTypeInferrer {
protected JetType result;
protected DataFlowInfo resultDataFlowInfo;
protected final JetType extectedType;
protected final JetType extectedReturnType;
protected final JetType expectedType;
protected final JetType expectedReturnType;
// protected WritableScope resultScope;
private TypeInferrerVisitor(@NotNull JetScope scope, boolean preferBlock, @NotNull DataFlowInfo dataFlowInfo, @Nullable JetType expectedType, @Nullable JetType expectedReturnType) {
private TypeInferrerVisitor(@NotNull JetScope scope, boolean preferBlock, @NotNull DataFlowInfo dataFlowInfo, @NotNull JetType expectedType, @Nullable JetType expectedReturnType) {
this.scope = scope;
this.preferBlock = preferBlock;
this.dataFlowInfo = dataFlowInfo;
this.extectedType = expectedType;
this.extectedReturnType = expectedReturnType;
this.expectedType = expectedType;
this.expectedReturnType = expectedReturnType;
}
@Nullable
@@ -702,29 +730,19 @@ public class JetTypeInferrer {
return resultDataFlowInfo;
}
// public WritableScope getResultScope() {
// if (resultScope instanceof WritableScopeImpl) {
// WritableScopeImpl writableScope = (WritableScopeImpl) resultScope;
// if (!writableScope.hasDeclaredItems()) {
// return null;
// }
// }
// return resultScope;
// }
//
@Nullable
public JetType getType(@NotNull JetScope scope, @NotNull JetExpression expression, boolean preferBlock) {
return getType(scope, expression, preferBlock, dataFlowInfo);
return getTypeWithNewDataFlowInfo(scope, expression, preferBlock, dataFlowInfo);
}
@Nullable
public JetType getType(@NotNull final JetScope scope, @NotNull JetExpression expression, final boolean preferBlock, @NotNull DataFlowInfo dataFlowInfo) {
public JetType getTypeWithNewDataFlowInfo(@NotNull final JetScope scope, @NotNull JetExpression expression, final boolean preferBlock, @NotNull DataFlowInfo dataFlowInfo) {
TypeInferrerVisitor visitor;
if (this.scope == scope && this.preferBlock == preferBlock && result == null && dataFlowInfo == this.dataFlowInfo) {
visitor = this;
}
else {
visitor = createNew(scope, preferBlock, dataFlowInfo, extectedType, extectedReturnType);
visitor = createNew(scope, preferBlock, dataFlowInfo, expectedType, expectedReturnType);
}
JetType type = visitor.getType(expression);
visitor.result = null;
@@ -732,14 +750,13 @@ public class JetTypeInferrer {
}
@NotNull
public TypeInferrerVisitor createNew(@NotNull JetScope scope, boolean preferBlock, @NotNull DataFlowInfo dataFlowInfo, @Nullable JetType expectedType, @Nullable JetType expectedReturnType) {
public TypeInferrerVisitor createNew(@NotNull JetScope scope, boolean preferBlock, @NotNull DataFlowInfo dataFlowInfo, @NotNull JetType expectedType, @Nullable JetType expectedReturnType) {
return new TypeInferrerVisitor(scope, preferBlock, dataFlowInfo, expectedType, expectedReturnType);
}
@Nullable
public final JetType getType(@NotNull JetExpression expression) {
assert result == null;
trace.recordResolutionScope(expression, scope);
if (trace.isProcessed(expression)) {
return trace.getBindingContext().getExpressionType(expression);
}
@@ -765,6 +782,9 @@ public class JetTypeInferrer {
result = null;
}
if (!trace.isProcessed(expression)) {
trace.recordResolutionScope(expression, scope);
}
trace.markAsProcessed(expression);
return result;
}
@@ -890,7 +910,7 @@ public class JetTypeInferrer {
public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) {
if (preferBlock && !expression.hasParameterSpecification()) {
trace.recordBlock(expression);
result = getBlockReturnedType(scope, expression.getBody(), dataFlowInfo, extectedReturnType);
result = getBlockReturnedType(scope, expression.getBody(), dataFlowInfo, expectedReturnType);
return;
}
@@ -934,12 +954,12 @@ public class JetTypeInferrer {
if (returnTypeRef != null) {
returnType = typeResolver.resolveType(scope, returnTypeRef);
} else {
WritableScope writableScope = new WritableScopeImpl(scope, functionDescriptor, trace.getErrorHandler());
WritableScope writableScope = new WritableScopeImpl(scope, functionDescriptor, trace.getErrorHandler()).setDebugName("Inner scope of a function literal");
for (VariableDescriptor variableDescriptor : valueParameterDescriptors) {
writableScope.addVariableDescriptor(variableDescriptor);
}
writableScope.setThisType(receiverType);
returnType = getBlockReturnedType(writableScope, expression.getBody(), dataFlowInfo, extectedReturnType);
returnType = getBlockReturnedType(writableScope, expression.getBody(), dataFlowInfo, expectedReturnType);
}
JetType safeReturnType = returnType == null ? ErrorUtils.createErrorType("<return type>") : returnType;
functionDescriptor.setReturnType(safeReturnType);
@@ -1016,7 +1036,7 @@ public class JetTypeInferrer {
@Override
public void visitReturnExpression(JetReturnExpression expression) {
if (extectedReturnType == FORBIDDEN) {
if (expectedReturnType == FORBIDDEN) {
trace.getErrorHandler().genericError(expression.getNode(), "'return' is not allowed here");
return;
}
@@ -1027,14 +1047,14 @@ public class JetTypeInferrer {
returnedType = getType(scope, returnedExpression, false);
}
else {
if (extectedReturnType != null && !JetStandardClasses.isUnit(extectedReturnType)) {
trace.getErrorHandler().genericError(expression.getNode(), "This function must return a value of type " + extectedReturnType);
if (expectedReturnType != null && !JetStandardClasses.isUnit(expectedReturnType)) {
trace.getErrorHandler().genericError(expression.getNode(), "This function must return a value of type " + expectedReturnType);
}
}
if (extectedReturnType != null && returnedType != null) {
if (!semanticServices.getTypeChecker().isSubtypeOf(returnedType, extectedReturnType)) {
trace.getErrorHandler().typeMismatch(returnedExpression == null ? expression : returnedExpression, extectedReturnType, returnedType);
if (expectedReturnType != null && returnedType != null) {
if (!semanticServices.getTypeChecker().isSubtypeOf(returnedType, expectedReturnType)) {
trace.getErrorHandler().typeMismatch(returnedExpression == null ? expression : returnedExpression, expectedReturnType, returnedType);
}
}
@@ -1053,7 +1073,7 @@ public class JetTypeInferrer {
@Override
public void visitTypeofExpression(JetTypeofExpression expression) {
JetType type = safeGetType(scope, expression.getBaseExpression(), false, null); // TODO
JetType type = safeGetType(scope, expression.getBaseExpression(), false, NO_EXPECTED_TYPE); // TODO
result = semanticServices.getStandardLibrary().getTypeInfoType(type);
}
@@ -1109,7 +1129,7 @@ public class JetTypeInferrer {
List<JetExpression> entries = expression.getEntries();
List<JetType> types = new ArrayList<JetType>();
for (JetExpression entry : entries) {
types.add(safeGetType(scope, entry, false, null)); // TODO
types.add(safeGetType(scope, entry, false, NO_EXPECTED_TYPE)); // TODO
}
// TODO : labels
result = JetStandardClasses.getTupleType(types);
@@ -1217,7 +1237,7 @@ public class JetTypeInferrer {
@Override
public void visitBlockExpression(JetBlockExpression expression) {
result = getBlockReturnedType(scope, expression.getStatements(), dataFlowInfo, extectedReturnType);
result = getBlockReturnedType(scope, expression.getStatements(), dataFlowInfo, expectedReturnType);
}
@Override
@@ -1225,7 +1245,7 @@ public class JetTypeInferrer {
// TODO :change scope according to the bound value in the when header
final JetExpression subjectExpression = expression.getSubjectExpression();
final JetType subjectType = subjectExpression != null ? safeGetType(scope, subjectExpression, false, null) : ErrorUtils.createErrorType("Unknown type");
final JetType subjectType = subjectExpression != null ? safeGetType(scope, subjectExpression, false, NO_EXPECTED_TYPE) : ErrorUtils.createErrorType("Unknown type");
final VariableDescriptor variableDescriptor = subjectExpression != null ? getVariableDescriptorFromSimpleName(subjectExpression) : null;
// TODO : exhaustive patterns
@@ -1233,7 +1253,7 @@ public class JetTypeInferrer {
Set<JetType> expressionTypes = Sets.newHashSet();
for (JetWhenEntry whenEntry : expression.getEntries()) {
JetWhenCondition condition = whenEntry.getCondition();
WritableScope scopeToExtend = newWritableScopeImpl();
WritableScope scopeToExtend = newWritableScopeImpl().setDebugName("Scope extended in when entry");
DataFlowInfo newDataFlowInfo = dataFlowInfo;
if (condition != null) {
newDataFlowInfo = checkWhenCondition(subjectExpression, subjectType, condition, scopeToExtend, variableDescriptor);
@@ -1241,7 +1261,7 @@ public class JetTypeInferrer {
JetWhenExpression subWhen = whenEntry.getSubWhen();
JetExpression bodyExpression = subWhen == null ? whenEntry.getExpression() : subWhen;
if (bodyExpression != null) {
JetType type = getType(scopeToExtend, bodyExpression, true, newDataFlowInfo);
JetType type = getTypeWithNewDataFlowInfo(scopeToExtend, bodyExpression, true, newDataFlowInfo);
if (type != null) {
expressionTypes.add(type);
}
@@ -1419,7 +1439,7 @@ public class JetTypeInferrer {
if (catchParameter != null) {
VariableDescriptor variableDescriptor = classDescriptorResolver.resolveLocalVariableDescriptor(scope.getContainingDeclaration(), scope, catchParameter);
if (catchBody != null) {
WritableScope catchScope = newWritableScopeImpl();
WritableScope catchScope = newWritableScopeImpl().setDebugName("Catch scope");
catchScope.addVariableDescriptor(variableDescriptor);
JetType type = getType(catchScope, catchBody, true);
if (type != null) {
@@ -1455,13 +1475,13 @@ public class JetTypeInferrer {
JetExpression elseBranch = expression.getElse();
JetExpression thenBranch = expression.getThen();
WritableScopeImpl thenScope = newWritableScopeImpl();
WritableScopeImpl thenScope = newWritableScopeImpl().setDebugName("Then scope");
DataFlowInfo thenInfo = extractDataFlowInfoFromCondition(condition, true, thenScope);
DataFlowInfo elseInfo = extractDataFlowInfoFromCondition(condition, false, null);
if (elseBranch == null) {
if (thenBranch != null) {
JetType type = getType(thenScope, thenBranch, true, thenInfo);
JetType type = getTypeWithNewDataFlowInfo(thenScope, thenBranch, true, thenInfo);
if (type != null && JetStandardClasses.isNothing(type)) {
resultDataFlowInfo = elseInfo;
// resultScope = elseScope;
@@ -1470,7 +1490,7 @@ public class JetTypeInferrer {
}
}
else if (thenBranch == null) {
JetType type = getType(scope, elseBranch, true, elseInfo);
JetType type = getTypeWithNewDataFlowInfo(scope, elseBranch, true, elseInfo);
if (type != null && JetStandardClasses.isNothing(type)) {
resultDataFlowInfo = thenInfo;
// resultScope = thenScope;
@@ -1478,8 +1498,8 @@ public class JetTypeInferrer {
result = JetStandardClasses.getUnitType();
}
else {
JetType thenType = getType(thenScope, thenBranch, true, thenInfo);
JetType elseType = getType(scope, elseBranch, true, elseInfo);
JetType thenType = getTypeWithNewDataFlowInfo(thenScope, thenBranch, true, thenInfo);
JetType elseType = getTypeWithNewDataFlowInfo(scope, elseBranch, true, elseInfo);
if (thenType == null) {
result = elseType;
@@ -1647,9 +1667,9 @@ public class JetTypeInferrer {
checkCondition(scope, condition);
JetExpression body = expression.getBody();
if (body != null) {
WritableScopeImpl scopeToExtend = newWritableScopeImpl();
WritableScopeImpl scopeToExtend = newWritableScopeImpl().setDebugName("Scope extended in while's condition");
DataFlowInfo conditionInfo = condition == null ? dataFlowInfo : extractDataFlowInfoFromCondition(condition, true, scopeToExtend);
getType(scopeToExtend, body, true, conditionInfo);
getTypeWithNewDataFlowInfo(scopeToExtend, body, true, conditionInfo);
}
if (!flowInformationProvider.isBreakable(expression)) {
// resultScope = newWritableScopeImpl();
@@ -1665,18 +1685,18 @@ public class JetTypeInferrer {
if (body instanceof JetFunctionLiteralExpression) {
JetFunctionLiteralExpression function = (JetFunctionLiteralExpression) body;
if (!function.hasParameterSpecification()) {
WritableScope writableScope = newWritableScopeImpl();
WritableScope writableScope = newWritableScopeImpl().setDebugName("do..while body scope");
conditionScope = writableScope;
getBlockReturnedTypeWithWritableScope(writableScope, function.getBody(), dataFlowInfo, extectedReturnType);
getBlockReturnedTypeWithWritableScope(writableScope, function.getBody(), dataFlowInfo, expectedReturnType);
trace.recordBlock(function);
} else {
getType(scope, body, true);
}
}
else if (body != null) {
WritableScope writableScope = newWritableScopeImpl();
WritableScope writableScope = newWritableScopeImpl().setDebugName("do..while body scope");
conditionScope = writableScope;
getBlockReturnedTypeWithWritableScope(writableScope, Collections.singletonList(body), dataFlowInfo, extectedReturnType);
getBlockReturnedTypeWithWritableScope(writableScope, Collections.singletonList(body), dataFlowInfo, expectedReturnType);
}
JetExpression condition = expression.getCondition();
checkCondition(conditionScope, condition);
@@ -1708,7 +1728,7 @@ public class JetTypeInferrer {
expectedParameterType = checkIterableConvention(loopRangeType, loopRange.getNode());
}
WritableScope loopScope = newWritableScopeImpl();
WritableScope loopScope = newWritableScopeImpl().setDebugName("Scope with for-loop index");
if (loopParameter != null) {
JetTypeReference typeReference = loopParameter.getTypeReference();
@@ -1811,8 +1831,82 @@ public class JetTypeInferrer {
// // TODO : type argument inference
// JetTypeReference typeReference = expression.getTypeReference();
// if (typeReference != null) {
// result = checkConstructorCall(scope, typeReference, expression);
// result = checkTypeInitializerCall(scope, typeReference, expression);
// }
// }
// private void resolveCallWithExplicitName(@NotNull JetScope scope, JetExpression receiver, String functionName, List<JetType> resolvedTypeArguments, List<ValueArgumentPsi> valueArguments) {
//
// boolean someNamed = false;
// boolean allNamed = true;
// for (ValueArgumentPsi valueArgument : valueArguments) {
// if (valueArgument.isNamed()) {
// trace.getErrorHandler().genericError(valueArgument.asElement().getNode(), "Named arguments are not supported");
// someNamed = true;
// }
// else {
// allNamed = false;
// }
// }
// if (someNamed) {
// return; // TODO
// }
// if (someNamed && !allNamed) {
// // TODO function literals outside parentheses
// }
//
// ErrorHandlerWithRegions errorHandler = trace.getErrorHandler();
//
// // 1. resolve 'receiver' in 'scope' with expected type 'NO_EXPECTED_TYPE'
// errorHandler.openRegion();
// JetType receiverType = JetTypeInferrer.this.getType(scope, receiver, false, NO_EXPECTED_TYPE);
// // for each applicable function in 'receiverType'
// Set<FunctionDescriptor> allFunctions = receiverType.getMemberScope().getFunctionGroup(functionName).getFunctionDescriptors();
// Map<FunctionDescriptor, List<JetType>> applicableFunctions = Maps.newHashMap();
// int typeArgCount = resolvedTypeArguments.size();
// int valueArgCount = valueArguments.size();
// for (FunctionDescriptor functionDescriptor : allFunctions) {
// if (typeArgCount == 0 || functionDescriptor.getTypeParameters().size() == typeArgCount) {
// if (FunctionDescriptorUtil.getMinimumArity(functionDescriptor) <= valueArgCount &&
// valueArgCount <= FunctionDescriptorUtil.getMaximumArity(functionDescriptor)) {
// // get expected types for value parameters
// if (typeArgCount > 0) {
// FunctionDescriptor substitutedFunctionDescriptor = FunctionDescriptorUtil.substituteFunctionDescriptor(resolvedTypeArguments, functionDescriptor);
// }
// else {
// FunctionDescriptor substitutedFunctionDescriptor = FunctionDescriptorUtil.substituteFunctionDescriptor(TypeUtils.getDefaultTypes(functionDescriptor.getTypeParameters()), functionDescriptor);
// List<JetType> valueArgumentTypes = getArgumentTypes(substitutedFunctionDescriptor, valueArguments);
// if (valueArgumentTypes == null) {
// Map<TypeConstructor, TypeProjection> noExpectedTypes = Maps.newHashMap();
// for (TypeParameterDescriptor typeParameterDescriptor : functionDescriptor.getTypeParameters()) {
// noExpectedTypes.put(typeParameterDescriptor.getTypeConstructor(), new TypeProjection(NO_EXPECTED_TYPE));
// }
// substitutedFunctionDescriptor = functionDescriptor.substitute(TypeSubstitutor.create(noExpectedTypes));
// valueArgumentTypes = getArgumentTypes(substitutedFunctionDescriptor, valueArguments);
// }
// if (valueArgumentTypes != null) {
// List<JetType> typeArguments = solveConstraintSystem(functionDescriptor, valueArgumentTypes, expectedReturnType);
// if (typeArguments != null) {
// applicableFunctions.put(functionDescriptor, typeArguments);
// }
// }
// }
// // type-check the parameters
// // if something was found (one or many options
// errorHandler.closeAndCommitCurrentRegion();
// // otherwise
// errorHandler.closeAndReturnCurrentRegion();
//
// }
// }
// }
// // get expected types for value parameters
// // type-check the parameters
// // if something was found (one or many options
// errorHandler.closeAndCommitCurrentRegion();
// // otherwise
// errorHandler.closeAndReturnCurrentRegion();
//
// }
@Override
@@ -1825,7 +1919,7 @@ public class JetTypeInferrer {
// TODO : functions as values
JetExpression selectorExpression = expression.getSelectorExpression();
JetExpression receiverExpression = expression.getReceiverExpression();
JetType receiverType = new TypeInferrerVisitorWithNamespaces(scope, false, dataFlowInfo, null, null).getType(receiverExpression);
JetType receiverType = new TypeInferrerVisitorWithNamespaces(scope, false, dataFlowInfo, NO_EXPECTED_TYPE, null).getType(receiverExpression);
if (receiverType != null) {
ErrorHandlerWithRegions errorHandler = trace.getErrorHandler();
errorHandler.openRegion();
@@ -1989,7 +2083,7 @@ public class JetTypeInferrer {
JetType knownType = getType(scope, expression.getLeftHandSide(), false);
JetPattern pattern = expression.getPattern();
if (pattern != null && knownType != null) {
WritableScopeImpl scopeToExtend = newWritableScopeImpl();
WritableScopeImpl scopeToExtend = newWritableScopeImpl().setDebugName("Scope extended in 'is'");
DataFlowInfo newDataFlowInfo = checkPatternType(pattern, knownType, scopeToExtend, getVariableDescriptorFromSimpleName(expression.getLeftHandSide()));
patternsToDataFlowInfo.put(pattern, newDataFlowInfo);
patternsToBoundVariableLists.put(pattern, scopeToExtend.getDeclaredVariables());
@@ -2114,10 +2208,10 @@ public class JetTypeInferrer {
}
else if (operationType == JetTokens.ANDAND || operationType == JetTokens.OROR) {
JetType leftType = getType(scope, left, false);
WritableScopeImpl leftScope = newWritableScopeImpl();
WritableScopeImpl leftScope = newWritableScopeImpl().setDebugName("Left scope of && or ||");
DataFlowInfo flowInfoLeft = extractDataFlowInfoFromCondition(left, operationType == JetTokens.ANDAND, leftScope); // TODO: This gets computed twice: here and in extractDataFlowInfoFromCondition() for the whole condition
WritableScopeImpl rightScope = operationType == JetTokens.ANDAND ? leftScope : newWritableScopeImpl();
JetType rightType = right == null ? null : getType(rightScope, right, false, flowInfoLeft);
WritableScopeImpl rightScope = operationType == JetTokens.ANDAND ? leftScope : newWritableScopeImpl().setDebugName("Right scope of && or ||");
JetType rightType = right == null ? null : getTypeWithNewDataFlowInfo(rightScope, right, false, flowInfoLeft);
if (leftType != null && !isBoolean(leftType)) {
trace.getErrorHandler().typeMismatch(left, semanticServices.getStandardLibrary().getBooleanType(), leftType);
}
@@ -2202,7 +2296,7 @@ public class JetTypeInferrer {
@Nullable
protected List<JetType> getTypes(JetScope scope, List<JetExpression> indexExpressions) {
List<JetType> argumentTypes = new ArrayList<JetType>();
TypeInferrerVisitor typeInferrerVisitor = new TypeInferrerVisitor(scope, false, dataFlowInfo, null, null);
TypeInferrerVisitor typeInferrerVisitor = new TypeInferrerVisitor(scope, false, dataFlowInfo, NO_EXPECTED_TYPE, null);
for (JetExpression indexExpression : indexExpressions) {
JetType type = typeInferrerVisitor.getType(indexExpression);
if (type == null) {
@@ -2293,7 +2387,7 @@ public class JetTypeInferrer {
}
private class TypeInferrerVisitorWithNamespaces extends TypeInferrerVisitor {
private TypeInferrerVisitorWithNamespaces(@NotNull JetScope scope, boolean preferBlock, @NotNull DataFlowInfo dataFlowInfo, @Nullable JetType expectedType, @Nullable JetType expectedReturnType) {
private TypeInferrerVisitorWithNamespaces(@NotNull JetScope scope, boolean preferBlock, @NotNull DataFlowInfo dataFlowInfo, @NotNull JetType expectedType, @Nullable JetType expectedReturnType) {
super(scope, preferBlock, dataFlowInfo, expectedType, expectedReturnType);
}
@@ -2304,7 +2398,7 @@ public class JetTypeInferrer {
@NotNull
@Override
public TypeInferrerVisitor createNew(@NotNull JetScope scope, boolean preferBlock, @NotNull DataFlowInfo dataFlowInfo, @Nullable JetType expectedType, @Nullable JetType expectedReturnType) {
public TypeInferrerVisitor createNew(@NotNull JetScope scope, boolean preferBlock, @NotNull DataFlowInfo dataFlowInfo, @NotNull JetType expectedType, @Nullable JetType expectedReturnType) {
return new TypeInferrerVisitorWithNamespaces(scope, preferBlock, dataFlowInfo, expectedType, expectedReturnType);
}
@@ -2324,7 +2418,7 @@ public class JetTypeInferrer {
private class TypeInferrerVisitorWithWritableScope extends TypeInferrerVisitor {
private final WritableScope scope;
public TypeInferrerVisitorWithWritableScope(@NotNull WritableScope scope, boolean preferBlock, DataFlowInfo dataFlowInfo, @Nullable JetType expectedType, @Nullable JetType expectedReturnType) {
public TypeInferrerVisitorWithWritableScope(@NotNull WritableScope scope, boolean preferBlock, DataFlowInfo dataFlowInfo, @NotNull JetType expectedType, @Nullable JetType expectedReturnType) {
super(scope, preferBlock, dataFlowInfo, expectedType, expectedReturnType);
this.scope = scope;
}
@@ -2459,8 +2553,8 @@ public class JetTypeInferrer {
@NotNull
@Override
public TypeInferrerVisitor createNew(@NotNull JetScope scope, boolean preferBlock, @NotNull DataFlowInfo dataFlowInfo, @Nullable JetType expectedType, @Nullable JetType expectedReturnType) {
WritableScopeImpl writableScope = newWritableScopeImpl(scope);
public TypeInferrerVisitor createNew(@NotNull JetScope scope, boolean preferBlock, @NotNull DataFlowInfo dataFlowInfo, @NotNull JetType expectedType, @Nullable JetType expectedReturnType) {
WritableScopeImpl writableScope = newWritableScopeImpl(scope).setDebugName("Block scope");
return new TypeInferrerVisitorWithWritableScope(writableScope, preferBlock, dataFlowInfo, expectedType, expectedReturnType);
}
}
@@ -177,7 +177,7 @@ public class TypeUtils {
@NotNull
public static JetType makeUnsubstitutedType(ClassDescriptor classDescriptor, JetScope unsubstitutedMemberScope) {
List<TypeProjection> arguments = getDefaultArguments(classDescriptor.getTypeConstructor().getParameters());
List<TypeProjection> arguments = getDefaultTypeProjections(classDescriptor.getTypeConstructor().getParameters());
return new JetTypeImpl(
Collections.<Annotation>emptyList(),
classDescriptor.getTypeConstructor(),
@@ -188,7 +188,7 @@ public class TypeUtils {
}
@NotNull
public static List<TypeProjection> getDefaultArguments(List<TypeParameterDescriptor> parameters) {
public static List<TypeProjection> getDefaultTypeProjections(List<TypeParameterDescriptor> parameters) {
List<TypeProjection> result = new ArrayList<TypeProjection>();
for (TypeParameterDescriptor parameterDescriptor : parameters) {
result.add(new TypeProjection(parameterDescriptor.getDefaultType()));
@@ -196,6 +196,15 @@ public class TypeUtils {
return result;
}
@NotNull
public static List<JetType> getDefaultTypes(List<TypeParameterDescriptor> parameters) {
List<JetType> result = Lists.newArrayList();
for (TypeParameterDescriptor parameterDescriptor : parameters) {
result.add(parameterDescriptor.getDefaultType());
}
return result;
}
@NotNull
public static Map<TypeConstructor, TypeProjection> buildSubstitutionContext(@NotNull JetType context) {
return buildSubstitutionContext(context.getConstructor().getParameters(), context.getArguments());
@@ -61,10 +61,6 @@ public class JetTestUtils {
public void removeStatementRecord(@NotNull JetElement statement) {
}
@Override
public void removeReferenceResolution(@NotNull JetReferenceExpression referenceExpression) {
}
@Override
public void requireBackingField(@NotNull PropertyDescriptor propertyDescriptor) {
}
@@ -493,14 +493,14 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
private void assertType(String expression, JetType expectedType) {
Project project = getProject();
JetExpression jetExpression = JetChangeUtil.createExpression(project, expression);
JetType type = semanticServices.getTypeInferrer(JetTestUtils.DUMMY, JetFlowInformationProvider.NONE).getType(classDefinitions.BASIC_SCOPE, jetExpression, false, null);
JetType type = semanticServices.getTypeInferrer(JetTestUtils.DUMMY, JetFlowInformationProvider.NONE).getType(classDefinitions.BASIC_SCOPE, jetExpression, false, JetTypeInferrer.NO_EXPECTED_TYPE);
assertTrue(type + " != " + expectedType, type.equals(expectedType));
}
private void assertErrorType(String expression) {
Project project = getProject();
JetExpression jetExpression = JetChangeUtil.createExpression(project, expression);
JetType type = semanticServices.getTypeInferrer(JetTestUtils.DUMMY, JetFlowInformationProvider.NONE).safeGetType(classDefinitions.BASIC_SCOPE, jetExpression, false, null);
JetType type = semanticServices.getTypeInferrer(JetTestUtils.DUMMY, JetFlowInformationProvider.NONE).safeGetType(classDefinitions.BASIC_SCOPE, jetExpression, false, JetTypeInferrer.NO_EXPECTED_TYPE);
assertTrue("Error type expected but " + type + " returned", ErrorUtils.isErrorType(type));
}
@@ -523,7 +523,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
private void assertType(JetScope scope, String expression, String expectedTypeStr) {
Project project = getProject();
JetExpression jetExpression = JetChangeUtil.createExpression(project, expression);
JetType type = semanticServices.getTypeInferrer(JetTestUtils.DUMMY, JetFlowInformationProvider.NONE).getType(scope, jetExpression, false, null);
JetType type = semanticServices.getTypeInferrer(JetTestUtils.DUMMY, JetFlowInformationProvider.NONE).getType(scope, jetExpression, false, JetTypeInferrer.NO_EXPECTED_TYPE);
JetType expectedType = expectedTypeStr == null ? null : makeType(expectedTypeStr);
assertEquals(expectedType, type);
}