浏览代码

reuse Validation Issue

Andreas Muelder 8 年之前
父节点
当前提交
e0789ae561

+ 56 - 57
plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/inferrer/TypeParameterInferrer.xtend

@@ -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));
+		}
 }
 		

+ 1 - 1
plugins/org.yakindu.base.types/src/org/yakindu/base/types/validation/IValidationIssueAcceptor.java

@@ -87,7 +87,7 @@ public interface IValidationIssueAcceptor {
 	}
 
 	public void accept(ValidationIssue trace);
-
+	
 	public static final class ListBasedValidationIssueAcceptor implements IValidationIssueAcceptor {
 
 		private List<ValidationIssue> traces = Lists.newArrayList();

+ 0 - 20
plugins/org.yakindu.base.types/src/org/yakindu/base/types/validation/TypeValidationError.java

@@ -1,20 +0,0 @@
-package org.yakindu.base.types.validation;
-
-@SuppressWarnings("serial")
-public class TypeValidationError {
-	private String errorCode;
-	private String message;
-	
-	public TypeValidationError(String msg, String errorCode) {
-		this.message = msg;
-		this.errorCode = errorCode;
-	}
-
-	public String getErrorCode() {
-		return errorCode;
-	}
-	
-	public String getMessage() {
-		return message;
-	}
-}

+ 49 - 44
plugins/org.yakindu.base.types/src/org/yakindu/base/types/validation/TypeValidator.java

@@ -1,3 +1,13 @@
+/**
+ * Copyright (c) 2015 committers of YAKINDU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * Contributors:
+ * 	committers of YAKINDU - initial API and implementation
+ * 
+ */
 package org.yakindu.base.types.validation;
 
 import static org.yakindu.base.types.inferrer.AbstractTypeSystemInferrer.ASSERT_COMPATIBLE;
@@ -7,103 +17,98 @@ import static org.yakindu.base.types.inferrer.ITypeSystemInferrer.NOT_COMPATIBLE
 import static org.yakindu.base.types.inferrer.ITypeSystemInferrer.NOT_SAME_CODE;
 import static org.yakindu.base.types.inferrer.ITypeSystemInferrer.NOT_TYPE_CODE;
 
-import java.util.ArrayList;
 import java.util.List;
 
 import org.yakindu.base.types.ComplexType;
 import org.yakindu.base.types.inferrer.ITypeSystemInferrer.InferenceResult;
 import org.yakindu.base.types.typesystem.ITypeSystem;
+import org.yakindu.base.types.validation.IValidationIssueAcceptor.ValidationIssue;
+import org.yakindu.base.types.validation.IValidationIssueAcceptor.ValidationIssue.Severity;
 
 import com.google.inject.Inject;
 
 public class TypeValidator {
+
 	@Inject
 	protected ITypeSystem registry;
-	
-	public List<TypeValidationError> assertNotType(InferenceResult currentResult, String msg, InferenceResult... candidates) {
-		List<TypeValidationError> errors = new ArrayList<>();
+
+	public void assertNotType(InferenceResult currentResult, String msg, IValidationIssueAcceptor acceptor,
+			InferenceResult... candidates) {
 		if (currentResult == null)
-			return errors;
+			return;
 		for (InferenceResult type : candidates) {
 			if (registry.isSame(currentResult.getType(), type.getType())) {
 				msg = msg != null ? msg : String.format(ASSERT_NOT_TYPE, currentResult);
-				errors.add(new TypeValidationError(msg, NOT_TYPE_CODE));
+				acceptor.accept(new ValidationIssue(Severity.ERROR, msg, NOT_TYPE_CODE));
 			}
 		}
-		return errors;
 	}
 
-	public List<TypeValidationError> assertSame(InferenceResult result1, InferenceResult result2, String msg) {
-		List<TypeValidationError> errors = new ArrayList<>();
+	public void assertSame(InferenceResult result1, InferenceResult result2, String msg,
+			IValidationIssueAcceptor acceptor) {
 		if (result1 == null || result2 == null)
-			return errors;
+			return;
 		if (!registry.isSame(result1.getType(), result2.getType())) {
 			msg = msg != null ? msg : String.format(ASSERT_SAME, result1, result2);
-			errors.add(new TypeValidationError(msg, NOT_SAME_CODE));
-			return errors;
+			acceptor.accept(new ValidationIssue(Severity.ERROR, msg, NOT_SAME_CODE));
+			return;
 		}
 
-		return assertTypeBindingsSame(result1, result2, msg);
+		assertTypeBindingsSame(result1, result2, msg, acceptor);
 	}
 
-	public List<TypeValidationError> assertCompatible(InferenceResult result1, InferenceResult result2, String msg) {
-		List<TypeValidationError> errors = new ArrayList<>();
-		if (result1 == null || result2 == null)
-			return errors;
-		if (isNullOnComplexType(result1, result2) || isNullOnComplexType(result2, result1)) {
-			return errors;
+	public void assertCompatible(InferenceResult result1, InferenceResult result2, String msg,
+			IValidationIssueAcceptor acceptor) {
+		if (result1 == null || result2 == null || isNullOnComplexType(result1, result2)
+				|| isNullOnComplexType(result2, result1)) {
+			return;
 		}
 		if (!registry.haveCommonType(result1.getType(), result2.getType())) {
 			msg = msg != null ? msg : String.format(ASSERT_COMPATIBLE, result1, result2);
-			errors.add(new TypeValidationError(msg, NOT_COMPATIBLE_CODE));
-			return errors;
+			acceptor.accept(new ValidationIssue(Severity.ERROR, msg, NOT_COMPATIBLE_CODE));
+			return;
 		}
-		return assertTypeBindingsSame(result1, result2, msg);
+		assertTypeBindingsSame(result1, result2, msg, acceptor);
 
 	}
 
-	public List<TypeValidationError> assertAssignable(InferenceResult varResult, InferenceResult valueResult, String msg) {
-		List<TypeValidationError> errors = new ArrayList<>();
-		if (varResult == null || valueResult == null)
-			return errors;
-		if (isNullOnComplexType(varResult, valueResult)) {
-			return errors;
+	public void assertAssignable(InferenceResult varResult, InferenceResult valueResult, String msg,
+			IValidationIssueAcceptor acceptor) {
+		if (varResult == null || valueResult == null || isNullOnComplexType(varResult, valueResult)) {
+			return;
 		}
 		if (!registry.isSuperType(valueResult.getType(), varResult.getType())) {
 			msg = msg != null ? msg : String.format(ASSERT_COMPATIBLE, varResult, valueResult);
-			errors.add(new TypeValidationError(msg, NOT_COMPATIBLE_CODE));
-			return errors;
+			acceptor.accept(new ValidationIssue(Severity.ERROR, msg, NOT_COMPATIBLE_CODE));
+			return;
 		}
-		return assertTypeBindingsSame(varResult, valueResult, msg);
+		assertTypeBindingsSame(varResult, valueResult, msg, acceptor);
 	}
 
-	public List<TypeValidationError> assertTypeBindingsSame(InferenceResult result1, InferenceResult result2, String msg) {
-		List<TypeValidationError> errors = new ArrayList<>();
+	public void assertTypeBindingsSame(InferenceResult result1, InferenceResult result2, String msg,
+			IValidationIssueAcceptor acceptor) {
 		List<InferenceResult> bindings1 = result1.getBindings();
 		List<InferenceResult> bindings2 = result2.getBindings();
 		msg = msg != null ? msg : String.format(ASSERT_COMPATIBLE, result1, result2);
 		if (bindings1.size() != bindings2.size()) {
-			errors.add(new TypeValidationError(msg, NOT_COMPATIBLE_CODE));
-			return errors;
+			acceptor.accept(new ValidationIssue(Severity.ERROR, msg, NOT_COMPATIBLE_CODE));
+			return;
 		}
 		for (int i = 0; i < bindings1.size(); i++) {
-			errors.addAll(assertSame(bindings1.get(i), bindings2.get(i), msg));
+			assertSame(bindings1.get(i), bindings2.get(i), msg, acceptor);
 		}
-		return errors;
 	}
 
-	public List<TypeValidationError> assertIsSubType(InferenceResult subResult, InferenceResult superResult, String msg) {
-		List<TypeValidationError> errors = new ArrayList<>();
+	public void assertIsSubType(InferenceResult subResult, InferenceResult superResult, String msg,
+			IValidationIssueAcceptor acceptor) {
 		if (subResult == null || superResult == null)
-			return errors;
+			return;
 		if (!registry.isSuperType(subResult.getType(), superResult.getType())) {
 			msg = msg != null ? msg : String.format(ASSERT_COMPATIBLE, subResult, superResult);
-			errors.add(new TypeValidationError(msg, NOT_COMPATIBLE_CODE));
-			return errors;
+			acceptor.accept(new ValidationIssue(Severity.ERROR, msg, NOT_COMPATIBLE_CODE));
 		}
-		return errors;
 	}
-	
+
 	public boolean isNullOnComplexType(InferenceResult result1, InferenceResult result2) {
 		return result1.getType() instanceof ComplexType
 				&& registry.isSame(result2.getType(), registry.getType(ITypeSystem.NULL));