|
@@ -13,12 +13,14 @@ package org.yakindu.base.expressions.inferrer
|
|
|
import com.google.inject.Inject
|
|
|
import java.util.List
|
|
|
import java.util.Map
|
|
|
+import org.yakindu.base.types.ComplexType
|
|
|
import org.yakindu.base.types.GenericElement
|
|
|
import org.yakindu.base.types.Parameter
|
|
|
+import org.yakindu.base.types.PrimitiveType
|
|
|
+import org.yakindu.base.types.Property
|
|
|
import org.yakindu.base.types.Type
|
|
|
import org.yakindu.base.types.TypeParameter
|
|
|
import org.yakindu.base.types.TypeSpecifier
|
|
|
-import org.yakindu.base.types.Property
|
|
|
import org.yakindu.base.types.inferrer.ITypeSystemInferrer.InferenceResult
|
|
|
import org.yakindu.base.types.typesystem.ITypeSystem
|
|
|
import org.yakindu.base.types.validation.IValidationIssueAcceptor
|
|
@@ -27,11 +29,8 @@ import org.yakindu.base.types.validation.IValidationIssueAcceptor.ValidationIssu
|
|
|
import org.yakindu.base.types.validation.TypeValidator
|
|
|
|
|
|
import static org.yakindu.base.expressions.inferrer.ExpressionsTypeInferrerMessages.*
|
|
|
-import static org.yakindu.base.types.inferrer.ITypeSystemInferrer.NOT_INFERRABLE_TYPE_PARAMETER_CODE
|
|
|
import static org.yakindu.base.types.inferrer.ITypeSystemInferrer.NOT_COMPATIBLE_CODE
|
|
|
-import org.yakindu.base.types.validation.TypeValidationError
|
|
|
-import org.yakindu.base.types.PrimitiveType
|
|
|
-import org.yakindu.base.types.ComplexType
|
|
|
+import static org.yakindu.base.types.inferrer.ITypeSystemInferrer.NOT_INFERRABLE_TYPE_PARAMETER_CODE
|
|
|
|
|
|
/**
|
|
|
* Infers the actual type for a type parameter used in generic elements like operations or complex types.
|
|
@@ -67,28 +66,36 @@ class TypeParameterInferrer {
|
|
|
for (var i = 0; i < parameters.size(); i++) {
|
|
|
val parameter = parameters.get(i).typeSpecifier;
|
|
|
val argument = arguments.get(i);
|
|
|
- if (parameterContainsTypeParameter(parameter) && assertArgumentAndParameterSoftCompatible(argument, parameter, acceptor)) {
|
|
|
- inferTypeParameterFromOperationArgument(parameter, argument, inferredTypeParameterTypes, acceptor);
|
|
|
+ if (parameterContainsTypeParameter(parameter)) {
|
|
|
+ val listAcceptor = new IValidationIssueAcceptor.ListBasedValidationIssueAcceptor();
|
|
|
+ assertArgumentAndParameterSoftCompatible(argument, parameter, [
|
|
|
+ listAcceptor.accept(it);
|
|
|
+ acceptor.accept(it)
|
|
|
+ ])
|
|
|
+ if (listAcceptor.traces.empty) {
|
|
|
+ inferTypeParameterFromOperationArgument(parameter, argument, inferredTypeParameterTypes,
|
|
|
+ acceptor)
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
def boolean parameterContainsTypeParameter(TypeSpecifier specifier) {
|
|
|
val type = specifier.type
|
|
|
if (type instanceof PrimitiveType) {
|
|
|
return false
|
|
|
- }
|
|
|
- if(type instanceof TypeParameter) {
|
|
|
+ }
|
|
|
+ if (type instanceof TypeParameter) {
|
|
|
return true
|
|
|
- }
|
|
|
- if(type instanceof ComplexType) {
|
|
|
+ }
|
|
|
+ if (type instanceof ComplexType) {
|
|
|
val complexType = type as ComplexType
|
|
|
- if(complexType.typeParameters != null) {
|
|
|
+ if (complexType.typeParameters != null) {
|
|
|
return true;
|
|
|
} else {
|
|
|
- for(prop : complexType.features.filter(Property)) {
|
|
|
- if(prop.typeSpecifier.parameterContainsTypeParameter) {
|
|
|
+ for (prop : complexType.features.filter(Property)) {
|
|
|
+ if (prop.typeSpecifier.parameterContainsTypeParameter) {
|
|
|
return true
|
|
|
}
|
|
|
}
|
|
@@ -136,14 +143,13 @@ class TypeParameterInferrer {
|
|
|
} else {
|
|
|
val commonType = getCommonType(argumentType, typeInMap);
|
|
|
val errorMsg = String.format(INCOMPATIBLE_TYPES, argumentType.toString, typeInMap.toString)
|
|
|
- val errors = typeValidator.assertTypeBindingsSame(argumentType, typeInMap, errorMsg)
|
|
|
- if (commonType == null || !errors.empty) {
|
|
|
+ val listAcceptor = new IValidationIssueAcceptor.ListBasedValidationIssueAcceptor();
|
|
|
+ typeValidator.assertTypeBindingsSame(argumentType, typeInMap, errorMsg, [
|
|
|
+ listAcceptor.accept(it);
|
|
|
+ acceptor.accept(it)
|
|
|
+ ])
|
|
|
+ if (commonType == null || !listAcceptor.traces.isEmpty) {
|
|
|
inferredTypeParameterTypes.put(typeParameter, null);
|
|
|
- if (!errors.empty) {
|
|
|
- errors.forEach [
|
|
|
- acceptor.error(message, errorCode)
|
|
|
- ]
|
|
|
- }
|
|
|
acceptor.error(
|
|
|
String.format(INFER_COMMON_TYPE, typeParameter.name,
|
|
|
newArrayList(argumentType.type.name, typeInMap.type.name)), NOT_INFERRABLE_TYPE_PARAMETER_CODE)
|
|
@@ -222,57 +228,50 @@ class TypeParameterInferrer {
|
|
|
IValidationIssueAcceptor acceptor) {
|
|
|
// I can't think of anything that's not compatible to a TypeParameter, so...
|
|
|
if (parameter.type instanceof TypeParameter) {
|
|
|
- return true
|
|
|
+ return
|
|
|
}
|
|
|
var result1 = InferenceResult.from(argumentResult.type) // ignore bindings
|
|
|
val result2 = InferenceResult.from(parameter.type)
|
|
|
- val errors = typeValidator.assertCompatible(result1, result2, null)
|
|
|
+ val listAcceptor = new IValidationIssueAcceptor.ListBasedValidationIssueAcceptor();
|
|
|
+ typeValidator.assertCompatible(result1, result2, null, [listAcceptor.accept(it); acceptor.accept(it)])
|
|
|
// check for correct number of TypeParameters / Argument's type parameters
|
|
|
- if (errors.empty && parameter.typeArguments != null &&
|
|
|
+ if (listAcceptor.traces.isEmpty && parameter.typeArguments != null &&
|
|
|
parameter.typeArguments.size != argumentResult.bindings.size) {
|
|
|
// build temporary binding list for error message
|
|
|
val bindings = parameter.typeArguments.map [
|
|
|
InferenceResult.from(type)
|
|
|
]
|
|
|
- errors.add(
|
|
|
- new TypeValidationError(
|
|
|
+ acceptor.accept(
|
|
|
+ new IValidationIssueAcceptor.ValidationIssue(ValidationIssue.Severity.ERROR,
|
|
|
String.format(INCOMPATIBLE_TYPES, argumentResult, InferenceResult.from(parameter.type, bindings)),
|
|
|
NOT_COMPATIBLE_CODE))
|
|
|
+ }
|
|
|
}
|
|
|
- if (!errors.empty) {
|
|
|
- errors.forEach [
|
|
|
- acceptor.error(message, errorCode)
|
|
|
- ]
|
|
|
- return false
|
|
|
- }
|
|
|
- return true
|
|
|
- }
|
|
|
|
|
|
- def error(IValidationIssueAcceptor acceptor, String msg, String issueCode) {
|
|
|
- acceptor.accept(new ValidationIssue(Severity.ERROR, msg, issueCode));
|
|
|
- }
|
|
|
-
|
|
|
- def error(IValidationIssueAcceptor acceptor, TypeSpecifier typeSpecifier, String issueCode) {
|
|
|
- acceptor.accept(
|
|
|
- new ValidationIssue(Severity.ERROR, String.format(INFER_TYPE_PARAMETER, typeSpecifier.type.name),
|
|
|
- issueCode));
|
|
|
- }
|
|
|
+ def error(IValidationIssueAcceptor acceptor, String msg, String issueCode) {
|
|
|
+ acceptor.accept(new ValidationIssue(Severity.ERROR, msg, issueCode));
|
|
|
+ }
|
|
|
|
|
|
- def error(IValidationIssueAcceptor acceptor, TypeParameter typeParameter, String issueCode) {
|
|
|
- acceptor.accept(
|
|
|
- new ValidationIssue(Severity.ERROR, String.format(INFER_TYPE_PARAMETER, typeParameter.name),
|
|
|
- issueCode));
|
|
|
- }
|
|
|
+ def error(IValidationIssueAcceptor acceptor, TypeSpecifier typeSpecifier, String issueCode) {
|
|
|
+ acceptor.accept(
|
|
|
+ new ValidationIssue(Severity.ERROR, String.format(INFER_TYPE_PARAMETER, typeSpecifier.type.name),
|
|
|
+ issueCode));
|
|
|
+ }
|
|
|
|
|
|
- def warning(IValidationIssueAcceptor acceptor, String msg, String issueCode) {
|
|
|
- acceptor.accept(new ValidationIssue(Severity.WARNING, msg, issueCode))
|
|
|
- }
|
|
|
+ def error(IValidationIssueAcceptor acceptor, TypeParameter typeParameter, String issueCode) {
|
|
|
+ acceptor.accept(
|
|
|
+ new ValidationIssue(Severity.ERROR, String.format(INFER_TYPE_PARAMETER, typeParameter.name),
|
|
|
+ issueCode));
|
|
|
+ }
|
|
|
|
|
|
- def warning(IValidationIssueAcceptor acceptor, TypeParameter typeParameter, String issueCode) {
|
|
|
- acceptor.accept(
|
|
|
- new ValidationIssue(Severity.WARNING, String.format(INFER_TYPE_PARAMETER, typeParameter.name),
|
|
|
- issueCode));
|
|
|
- }
|
|
|
+ def warning(IValidationIssueAcceptor acceptor, String msg, String issueCode) {
|
|
|
+ acceptor.accept(new ValidationIssue(Severity.WARNING, msg, issueCode))
|
|
|
+ }
|
|
|
|
|
|
+ def warning(IValidationIssueAcceptor acceptor, TypeParameter typeParameter, String issueCode) {
|
|
|
+ acceptor.accept(
|
|
|
+ new ValidationIssue(Severity.WARNING, String.format(INFER_TYPE_PARAMETER, typeParameter.name),
|
|
|
+ issueCode));
|
|
|
+ }
|
|
|
}
|
|
|
|