KT-371 Resolve default parameters for constructors
This commit is contained in:
@@ -574,7 +574,11 @@ public class JetControlFlowProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitParameter(JetParameter parameter) {
|
public void visitParameter(JetParameter parameter) {
|
||||||
|
JetExpression defaultValue = parameter.getDefaultValue();
|
||||||
builder.declare(parameter);
|
builder.declare(parameter);
|
||||||
|
if (defaultValue != null) {
|
||||||
|
builder.read(defaultValue);
|
||||||
|
}
|
||||||
builder.write(parameter, parameter);
|
builder.write(parameter, parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -838,6 +842,10 @@ public class JetControlFlowProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitClass(JetClass klass) {
|
public void visitClass(JetClass klass) {
|
||||||
|
List<JetParameter> parameters = klass.getPrimaryConstructorParameters();
|
||||||
|
for (JetParameter parameter : parameters) {
|
||||||
|
value(parameter, inCondition);
|
||||||
|
}
|
||||||
visitClassOrObject(klass);
|
visitClassOrObject(klass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -262,7 +262,12 @@ public class JetFlowInformationProvider {
|
|||||||
}
|
}
|
||||||
if (!isInitialized && !varWithUninitializedErrorGenerated.contains(variableDescriptor)) {
|
if (!isInitialized && !varWithUninitializedErrorGenerated.contains(variableDescriptor)) {
|
||||||
varWithUninitializedErrorGenerated.add(variableDescriptor);
|
varWithUninitializedErrorGenerated.add(variableDescriptor);
|
||||||
trace.report(Errors.UNINITIALIZED_VARIABLE.on((JetSimpleNameExpression) element, variableDescriptor));
|
if (variableDescriptor instanceof ValueParameterDescriptor) {
|
||||||
|
trace.report(Errors.UNINITIALIZED_PARAMETER.on((JetSimpleNameExpression) element, (ValueParameterDescriptor) variableDescriptor));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
trace.report(Errors.UNINITIALIZED_VARIABLE.on((JetSimpleNameExpression) element, variableDescriptor));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -261,6 +261,9 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
|||||||
propertyDescriptor,
|
propertyDescriptor,
|
||||||
Lists.newArrayList(setter.getAnnotations()),
|
Lists.newArrayList(setter.getAnnotations()),
|
||||||
setter.hasBody(), setter.isDefault());
|
setter.hasBody(), setter.isDefault());
|
||||||
|
if (newSetter != null) {
|
||||||
|
newSetter.initialize(setter.getValueParameters().get(0).copy(newSetter));
|
||||||
|
}
|
||||||
propertyDescriptor.initialize(newGetter, newSetter);
|
propertyDescriptor.initialize(newGetter, newSetter);
|
||||||
return propertyDescriptor;
|
return propertyDescriptor;
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-10
@@ -1,6 +1,5 @@
|
|||||||
package org.jetbrains.jet.lang.descriptors;
|
package org.jetbrains.jet.lang.descriptors;
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||||
@@ -15,22 +14,28 @@ import java.util.Set;
|
|||||||
*/
|
*/
|
||||||
public class PropertySetterDescriptor extends PropertyAccessorDescriptor {
|
public class PropertySetterDescriptor extends PropertyAccessorDescriptor {
|
||||||
|
|
||||||
private MutableValueParameterDescriptor parameter;
|
private ValueParameterDescriptor parameter;
|
||||||
|
|
||||||
public PropertySetterDescriptor(@NotNull Modality modality, @NotNull Visibility visibility,
|
public PropertySetterDescriptor(@NotNull Modality modality,
|
||||||
@NotNull PropertyDescriptor correspondingProperty, @NotNull List<AnnotationDescriptor> annotations,
|
@NotNull Visibility visibility,
|
||||||
boolean hasBody, boolean isDefault)
|
@NotNull PropertyDescriptor correspondingProperty,
|
||||||
{
|
@NotNull List<AnnotationDescriptor> annotations,
|
||||||
|
boolean hasBody,
|
||||||
|
boolean isDefault) {
|
||||||
super(modality, visibility, correspondingProperty, annotations, "set-" + correspondingProperty.getName(), hasBody, isDefault);
|
super(modality, visibility, correspondingProperty, annotations, "set-" + correspondingProperty.getName(), hasBody, isDefault);
|
||||||
|
if (isDefault) {
|
||||||
|
initializeDefault();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize(@NotNull MutableValueParameterDescriptor parameter) {
|
public void initialize(@NotNull ValueParameterDescriptor parameter) {
|
||||||
assert this.parameter == null;
|
assert this.parameter == null;
|
||||||
this.parameter = parameter;
|
this.parameter = parameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setParameterType(@NotNull JetType type) {
|
public void initializeDefault() {
|
||||||
parameter.setType(type);
|
assert parameter == null;
|
||||||
|
parameter = new ValueParameterDescriptorImpl(this, 0, Collections.<AnnotationDescriptor>emptyList(), "<>", null, getCorrespondingProperty().getReturnType(), false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -42,7 +47,7 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<ValueParameterDescriptor> getValueParameters() {
|
public List<ValueParameterDescriptor> getValueParameters() {
|
||||||
return Collections.<ValueParameterDescriptor>singletonList(parameter);
|
return Collections.singletonList(parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -150,7 +150,8 @@ public interface Errors {
|
|||||||
};
|
};
|
||||||
PsiElementOnlyDiagnosticFactory3<JetModifierListOwner, CallableMemberDescriptor, CallableMemberDescriptor, DeclarationDescriptor> VIRTUAL_MEMBER_HIDDEN = PsiElementOnlyDiagnosticFactory3.create(ERROR, "''{0}'' hides ''{1}'' in class {2} and needs 'override' modifier", DescriptorRenderer.TEXT);
|
PsiElementOnlyDiagnosticFactory3<JetModifierListOwner, CallableMemberDescriptor, CallableMemberDescriptor, DeclarationDescriptor> VIRTUAL_MEMBER_HIDDEN = PsiElementOnlyDiagnosticFactory3.create(ERROR, "''{0}'' hides ''{1}'' in class {2} and needs 'override' modifier", DescriptorRenderer.TEXT);
|
||||||
|
|
||||||
PsiElementOnlyDiagnosticFactory1<JetSimpleNameExpression, DeclarationDescriptor> UNINITIALIZED_VARIABLE = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Variable ''{0}'' must be initialized", NAME);
|
PsiElementOnlyDiagnosticFactory1<JetSimpleNameExpression, VariableDescriptor> UNINITIALIZED_VARIABLE = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Variable ''{0}'' must be initialized", NAME);
|
||||||
|
PsiElementOnlyDiagnosticFactory1<JetSimpleNameExpression, ValueParameterDescriptor> UNINITIALIZED_PARAMETER = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Parameter ''{0}'' is uninitialized here", NAME);
|
||||||
UnusedElementDiagnosticFactory<JetProperty, VariableDescriptor> UNUSED_VARIABLE = UnusedElementDiagnosticFactory.create(WARNING, "Variable ''{0}'' is never used", NAME);
|
UnusedElementDiagnosticFactory<JetProperty, VariableDescriptor> UNUSED_VARIABLE = UnusedElementDiagnosticFactory.create(WARNING, "Variable ''{0}'' is never used", NAME);
|
||||||
UnusedElementDiagnosticFactory<JetParameter, VariableDescriptor> UNUSED_PARAMETER = UnusedElementDiagnosticFactory.create(WARNING, "Parameter ''{0}'' is never used", NAME);
|
UnusedElementDiagnosticFactory<JetParameter, VariableDescriptor> UNUSED_PARAMETER = UnusedElementDiagnosticFactory.create(WARNING, "Parameter ''{0}'' is never used", NAME);
|
||||||
UnusedElementDiagnosticFactory<JetNamedDeclaration, DeclarationDescriptor> ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE = UnusedElementDiagnosticFactory.create(WARNING, "Variable ''{0}'' is assigned but never accessed", NAME);
|
UnusedElementDiagnosticFactory<JetNamedDeclaration, DeclarationDescriptor> ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE = UnusedElementDiagnosticFactory.create(WARNING, "Variable ''{0}'' is assigned but never accessed", NAME);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.jetbrains.jet.lang.resolve;
|
|||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
|
import com.intellij.openapi.util.Pair;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import com.intellij.util.containers.Queue;
|
import com.intellij.util.containers.Queue;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -48,6 +49,7 @@ public class BodyResolver {
|
|||||||
|
|
||||||
resolvePropertyDeclarationBodies();
|
resolvePropertyDeclarationBodies();
|
||||||
resolveAnonymousInitializers();
|
resolveAnonymousInitializers();
|
||||||
|
resolvePrimaryConstructorParameters();
|
||||||
|
|
||||||
resolveSecondaryConstructorBodies();
|
resolveSecondaryConstructorBodies();
|
||||||
resolveFunctionBodies();
|
resolveFunctionBodies();
|
||||||
@@ -250,6 +252,17 @@ public class BodyResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void resolvePrimaryConstructorParameters() {
|
||||||
|
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
|
||||||
|
JetClass klass = entry.getKey();
|
||||||
|
MutableClassDescriptor classDescriptor = entry.getValue();
|
||||||
|
ConstructorDescriptor unsubstitutedPrimaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
|
||||||
|
if (unsubstitutedPrimaryConstructor != null) {
|
||||||
|
checkDefaultParameterValues(klass.getPrimaryConstructorParameters(), unsubstitutedPrimaryConstructor.getValueParameters(), classDescriptor.getScopeForInitializers());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void resolveSecondaryConstructorBodies() {
|
private void resolveSecondaryConstructorBodies() {
|
||||||
for (Map.Entry<JetSecondaryConstructor, ConstructorDescriptor> entry : this.context.getConstructors().entrySet()) {
|
for (Map.Entry<JetSecondaryConstructor, ConstructorDescriptor> entry : this.context.getConstructors().entrySet()) {
|
||||||
JetSecondaryConstructor constructor = entry.getKey();
|
JetSecondaryConstructor constructor = entry.getKey();
|
||||||
@@ -332,8 +345,10 @@ public class BodyResolver {
|
|||||||
if (bodyExpression != null) {
|
if (bodyExpression != null) {
|
||||||
ExpressionTypingServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace);
|
ExpressionTypingServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace);
|
||||||
|
|
||||||
typeInferrer.checkFunctionReturnType(scopeForConstructorBody, declaration, JetStandardClasses.getUnitType());
|
typeInferrer.checkFunctionReturnType(scopeForConstructorBody, declaration, descriptor, JetStandardClasses.getUnitType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkDefaultParameterValues(declaration.getValueParameters(), descriptor.getValueParameters(), scopeForConstructorBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolvePropertyDeclarationBodies() {
|
private void resolvePropertyDeclarationBodies() {
|
||||||
@@ -477,17 +492,25 @@ public class BodyResolver {
|
|||||||
if (!context.completeAnalysisNeeded(function)) return;
|
if (!context.completeAnalysisNeeded(function)) return;
|
||||||
|
|
||||||
JetExpression bodyExpression = function.getBodyExpression();
|
JetExpression bodyExpression = function.getBodyExpression();
|
||||||
|
JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(declaringScope, functionDescriptor, trace);
|
||||||
if (bodyExpression != null) {
|
if (bodyExpression != null) {
|
||||||
//JetFlowInformationProvider flowInformationProvider = context.getDescriptorResolver().computeFlowData(function.asElement(), bodyExpression);
|
|
||||||
ExpressionTypingServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace);
|
ExpressionTypingServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace);
|
||||||
|
|
||||||
typeInferrer.checkFunctionReturnType(declaringScope, function, functionDescriptor);
|
typeInferrer.checkFunctionReturnType(functionInnerScope, function, functionDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpressionTypingServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace);
|
|
||||||
List<JetParameter> valueParameters = function.getValueParameters();
|
List<JetParameter> valueParameters = function.getValueParameters();
|
||||||
|
List<ValueParameterDescriptor> valueParameterDescriptors = functionDescriptor.getValueParameters();
|
||||||
|
|
||||||
|
checkDefaultParameterValues(valueParameters, valueParameterDescriptors, functionInnerScope);
|
||||||
|
|
||||||
|
assert functionDescriptor.getReturnType() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkDefaultParameterValues(List<JetParameter> valueParameters, List<ValueParameterDescriptor> valueParameterDescriptors, JetScope declaringScope) {
|
||||||
|
ExpressionTypingServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace);
|
||||||
for (int i = 0; i < valueParameters.size(); i++) {
|
for (int i = 0; i < valueParameters.size(); i++) {
|
||||||
ValueParameterDescriptor valueParameterDescriptor = functionDescriptor.getValueParameters().get(i);
|
ValueParameterDescriptor valueParameterDescriptor = valueParameterDescriptors.get(i);
|
||||||
if (valueParameterDescriptor.hasDefaultValue()) {
|
if (valueParameterDescriptor.hasDefaultValue()) {
|
||||||
JetParameter jetParameter = valueParameters.get(i);
|
JetParameter jetParameter = valueParameters.get(i);
|
||||||
JetExpression defaultValue = jetParameter.getDefaultValue();
|
JetExpression defaultValue = jetParameter.getDefaultValue();
|
||||||
@@ -496,8 +519,6 @@ public class BodyResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert functionDescriptor.getReturnType() != null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void computeDeferredTypes() {
|
private void computeDeferredTypes() {
|
||||||
|
|||||||
@@ -707,6 +707,10 @@ public class DescriptorResolver {
|
|||||||
MutableValueParameterDescriptor valueParameterDescriptor = resolveValueParameterDescriptor(setterDescriptor, parameter, 0, type);
|
MutableValueParameterDescriptor valueParameterDescriptor = resolveValueParameterDescriptor(setterDescriptor, parameter, 0, type);
|
||||||
setterDescriptor.initialize(valueParameterDescriptor);
|
setterDescriptor.initialize(valueParameterDescriptor);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
setterDescriptor.initializeDefault();
|
||||||
|
}
|
||||||
|
|
||||||
trace.record(BindingContext.PROPERTY_ACCESSOR, setter, setterDescriptor);
|
trace.record(BindingContext.PROPERTY_ACCESSOR, setter, setterDescriptor);
|
||||||
}
|
}
|
||||||
else if (property.isVar()) {
|
else if (property.isVar()) {
|
||||||
@@ -841,11 +845,12 @@ public class DescriptorResolver {
|
|||||||
DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor),
|
DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor),
|
||||||
name == null ? "<no name>" : name
|
name == null ? "<no name>" : name
|
||||||
);
|
);
|
||||||
|
JetType inType = isMutable ? type : null;
|
||||||
|
propertyDescriptor.setType(inType, type, Collections.<TypeParameterDescriptor>emptyList(), ReceiverDescriptor.NO_RECEIVER);
|
||||||
|
|
||||||
PropertyGetterDescriptor getter = createDefaultGetter(propertyDescriptor);
|
PropertyGetterDescriptor getter = createDefaultGetter(propertyDescriptor);
|
||||||
PropertySetterDescriptor setter = createDefaultSetter(propertyDescriptor);
|
PropertySetterDescriptor setter = createDefaultSetter(propertyDescriptor);
|
||||||
|
|
||||||
JetType inType = isMutable ? type : null;
|
|
||||||
propertyDescriptor.setType(inType, type, Collections.<TypeParameterDescriptor>emptyList(), ReceiverDescriptor.NO_RECEIVER);
|
|
||||||
propertyDescriptor.initialize(getter, setter);
|
propertyDescriptor.initialize(getter, setter);
|
||||||
getter.initialize(propertyDescriptor.getOutType());
|
getter.initialize(propertyDescriptor.getOutType());
|
||||||
|
|
||||||
|
|||||||
+24
-18
@@ -18,13 +18,17 @@ 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;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
|
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.CommonSupertypes;
|
||||||
|
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||||
|
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||||
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.diagnostics.Errors.TYPE_MISMATCH;
|
import static org.jetbrains.jet.lang.diagnostics.Errors.TYPE_MISMATCH;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
import static org.jetbrains.jet.lang.resolve.BindingContext.LABEL_TARGET;
|
||||||
|
import static org.jetbrains.jet.lang.resolve.BindingContext.STATEMENT;
|
||||||
import static org.jetbrains.jet.lang.types.TypeUtils.FORBIDDEN;
|
import static org.jetbrains.jet.lang.types.TypeUtils.FORBIDDEN;
|
||||||
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
||||||
|
|
||||||
@@ -76,10 +80,6 @@ public class ExpressionTypingServices {
|
|||||||
// return ((ExpressionTypingContext) ExpressionTyperVisitorWithNamespaces).INSTANCE.getType(expression, ExpressionTypingContext.newRootContext(semanticServices, trace, scope, DataFlowInfo.getEmpty(), TypeUtils.NO_EXPECTED_TYPE, TypeUtils.NO_EXPECTED_TYPE));
|
// return ((ExpressionTypingContext) ExpressionTyperVisitorWithNamespaces).INSTANCE.getType(expression, ExpressionTypingContext.newRootContext(semanticServices, trace, scope, DataFlowInfo.getEmpty(), TypeUtils.NO_EXPECTED_TYPE, TypeUtils.NO_EXPECTED_TYPE));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkFunctionReturnType(@NotNull JetScope outerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor) {
|
|
||||||
checkFunctionReturnType(outerScope, function, functionDescriptor, DataFlowInfo.EMPTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JetType inferFunctionReturnType(@NotNull JetScope outerScope, JetDeclarationWithBody function, FunctionDescriptor functionDescriptor) {
|
public JetType inferFunctionReturnType(@NotNull JetScope outerScope, JetDeclarationWithBody function, FunctionDescriptor functionDescriptor) {
|
||||||
Map<JetExpression, JetType> typeMap = collectReturnedExpressionsWithTypes(trace, outerScope, function, functionDescriptor);
|
Map<JetExpression, JetType> typeMap = collectReturnedExpressionsWithTypes(trace, outerScope, function, functionDescriptor);
|
||||||
@@ -89,24 +89,30 @@ public class ExpressionTypingServices {
|
|||||||
: CommonSupertypes.commonSupertype(types);
|
: CommonSupertypes.commonSupertype(types);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkFunctionReturnType(JetScope functionInnerScope, JetDeclarationWithBody function, @NotNull final JetType expectedReturnType) {
|
|
||||||
checkFunctionReturnType(function, ExpressionTypingContext.newContext(
|
public void checkFunctionReturnType(@NotNull JetScope functionInnerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor) {
|
||||||
semanticServices, new HashMap<JetPattern, DataFlowInfo>(), new HashMap<JetPattern, List<VariableDescriptor>>(), new LabelResolver(),
|
checkFunctionReturnType(functionInnerScope, function, functionDescriptor, DataFlowInfo.EMPTY, null);
|
||||||
trace, functionInnerScope, DataFlowInfo.EMPTY, NO_EXPECTED_TYPE, expectedReturnType, false
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void checkFunctionReturnType(@NotNull JetScope functionInnerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor, @Nullable JetType expectedReturnType) {
|
||||||
|
checkFunctionReturnType(functionInnerScope, function, functionDescriptor, DataFlowInfo.EMPTY, expectedReturnType);
|
||||||
|
}
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/*package*/ void checkFunctionReturnType(@NotNull JetScope outerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor, DataFlowInfo dataFlowInfo) {
|
/*package*/ void checkFunctionReturnType(@NotNull JetScope functionInnerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor, @NotNull DataFlowInfo dataFlowInfo) {
|
||||||
JetType expectedReturnType = functionDescriptor.getReturnType();
|
checkFunctionReturnType(functionInnerScope, function, functionDescriptor, dataFlowInfo, null);
|
||||||
if (!function.hasBlockBody() && !function.hasDeclaredReturnType()) {
|
}
|
||||||
expectedReturnType = NO_EXPECTED_TYPE;
|
|
||||||
|
/*package*/ void checkFunctionReturnType(@NotNull JetScope functionInnerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor, @NotNull DataFlowInfo dataFlowInfo, @Nullable JetType expectedReturnType) {
|
||||||
|
if (expectedReturnType == null) {
|
||||||
|
expectedReturnType = functionDescriptor.getReturnType();
|
||||||
|
if (!function.hasBlockBody() && !function.hasDeclaredReturnType()) {
|
||||||
|
expectedReturnType = NO_EXPECTED_TYPE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace);
|
|
||||||
checkFunctionReturnType(function, ExpressionTypingContext.newContext(
|
checkFunctionReturnType(function, ExpressionTypingContext.newContext(
|
||||||
semanticServices, new HashMap<JetPattern, DataFlowInfo>(), new HashMap<JetPattern, List<VariableDescriptor>>(), new LabelResolver(),
|
semanticServices, new HashMap<JetPattern, DataFlowInfo>(), new HashMap<JetPattern, List<VariableDescriptor>>(), new LabelResolver(),
|
||||||
trace, functionInnerScope, dataFlowInfo, NO_EXPECTED_TYPE, expectedReturnType, false
|
trace, functionInnerScope, dataFlowInfo, NO_EXPECTED_TYPE, expectedReturnType, false
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -1,5 +1,6 @@
|
|||||||
package org.jetbrains.jet.lang.types.expressions;
|
package org.jetbrains.jet.lang.types.expressions;
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.Pair;
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -12,6 +13,7 @@ import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
|
|||||||
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
|
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||||
@@ -108,7 +110,8 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
|||||||
public JetType visitNamedFunction(JetNamedFunction function, ExpressionTypingContext context) {
|
public JetType visitNamedFunction(JetNamedFunction function, ExpressionTypingContext context) {
|
||||||
FunctionDescriptorImpl functionDescriptor = context.getDescriptorResolver().resolveFunctionDescriptor(scope.getContainingDeclaration(), scope, function);
|
FunctionDescriptorImpl functionDescriptor = context.getDescriptorResolver().resolveFunctionDescriptor(scope.getContainingDeclaration(), scope, function);
|
||||||
scope.addFunctionDescriptor(functionDescriptor);
|
scope.addFunctionDescriptor(functionDescriptor);
|
||||||
context.getServices().checkFunctionReturnType(context.scope, function, functionDescriptor, context.dataFlowInfo);
|
JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace);
|
||||||
|
context.getServices().checkFunctionReturnType(functionInnerScope, function, functionDescriptor, context.dataFlowInfo);
|
||||||
return checkExpectedType(function, context);
|
return checkExpectedType(function, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,15 @@
|
|||||||
val x = ""
|
val x = ""
|
||||||
|
|
||||||
fun bar(<!UNUSED_PARAMETER!>x<!> : Int = <!TYPE_MISMATCH!>""<!>, <!UNUSED_PARAMETER!>y<!> : Int = <!TYPE_MISMATCH!>x<!>, <!UNUSED_PARAMETER!>z<!> : String = <!UNRESOLVED_REFERENCE!>y<!>) {
|
fun bar(x : Int = <!TYPE_MISMATCH!>""<!>, y : Int = x, <!UNUSED_PARAMETER!>z<!> : String = <!TYPE_MISMATCH!>y<!>) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KT-371 Resolve default parameters for constructors
|
||||||
|
|
||||||
|
class A(x : Int = <!UNINITIALIZED_PARAMETER!>y<!>, y : Int = x) { // None of the references is resolved, no types checked
|
||||||
|
this(bool: Boolean, a: Int = <!TYPE_MISMATCH, UNINITIALIZED_PARAMETER!>b<!>, b: String = <!TYPE_MISMATCH!>a<!>) : this(1) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
val z = 3
|
||||||
|
|
||||||
|
fun foo(x: Int = <!UNINITIALIZED_PARAMETER!>y<!>, y: Int = x, <!UNUSED_PARAMETER!>i<!> : Int = z): Int = x + y
|
||||||
Reference in New Issue
Block a user