فهرست منبع

Added guard for proposal popup for conditional breakpoints. Added validation rule that checks expression evaluates to boolean

Andreas Mülder 12 سال پیش
والد
کامیت
ecd4be3ca3

+ 105 - 162
plugins/org.yakindu.sct.model.stext/src/org/yakindu/sct/model/stext/validation/STextJavaValidator.java

@@ -89,8 +89,7 @@ import com.google.inject.name.Named;
  * @auhor muelder
  * 
  */
-@ComposedChecks(validators = { SGraphJavaValidator.class,
-		SCTResourceValidator.class })
+@ComposedChecks(validators = { SGraphJavaValidator.class, SCTResourceValidator.class })
 public class STextJavaValidator extends AbstractSTextJavaValidator {
 
 	public static final String CHOICE_ONE_OUTGOING_DEFAULT_TRANSITION = "A choice should have one outgoing default transition";
@@ -116,6 +115,7 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 	public static final String EXIT_UNUSED = "The named exit is not used by outgoing transitions.";
 	public static final String EXIT_DEFAULT_UNUSED = "The parent composite state has no 'default' exit transition.";
 	public static final String TRANSITION_EXIT_SPEC_ON_MULTIPLE_SIBLINGS = "ExitPointSpec can't be used on transition siblings.";
+	public static final String CONDITIONAL_EXPRESSION = "The evaluation result of a conditional expression must be of type boolean";
 
 	@Inject
 	private ISTextTypeInferrer typeInferrer;
@@ -133,19 +133,17 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 	public void checkUnusedEntry(final Entry entry) {
 		if (entry.getParentRegion().getComposite() instanceof org.yakindu.sct.model.sgraph.State
 				&& entry.getIncomingTransitions().isEmpty()) {
-			org.yakindu.sct.model.sgraph.State state = (org.yakindu.sct.model.sgraph.State) entry
-					.getParentRegion().getComposite();
+			org.yakindu.sct.model.sgraph.State state = (org.yakindu.sct.model.sgraph.State) entry.getParentRegion()
+					.getComposite();
 
 			if (!STextValidationModelUtils.isDefault(entry)) {
 
 				boolean hasIncomingTransition = false;
-				Iterator<Transition> transitionIt = state
-						.getIncomingTransitions().iterator();
+				Iterator<Transition> transitionIt = state.getIncomingTransitions().iterator();
 
 				while (transitionIt.hasNext() && !hasIncomingTransition) {
 
-					Iterator<ReactionProperty> propertyIt = transitionIt.next()
-							.getProperties().iterator();
+					Iterator<ReactionProperty> propertyIt = transitionIt.next().getProperties().iterator();
 
 					while (propertyIt.hasNext() && !hasIncomingTransition) {
 
@@ -153,9 +151,7 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 
 						if (property instanceof EntryPointSpec) {
 
-							hasIncomingTransition = entry.getName()
-									.equals(((EntryPointSpec) property)
-											.getEntrypoint());
+							hasIncomingTransition = entry.getName().equals(((EntryPointSpec) property).getEntrypoint());
 						}
 					}
 				}
@@ -170,34 +166,29 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 	public void checkUnusedExit(final Exit exit) {
 		if (exit.getParentRegion().getComposite() instanceof org.yakindu.sct.model.sgraph.State
 				&& exit.getOutgoingTransitions().isEmpty()) {
-			org.yakindu.sct.model.sgraph.State state = (org.yakindu.sct.model.sgraph.State) exit
-					.getParentRegion().getComposite();
+			org.yakindu.sct.model.sgraph.State state = (org.yakindu.sct.model.sgraph.State) exit.getParentRegion()
+					.getComposite();
 
 			if (!STextValidationModelUtils.isDefault(exit)) {
 
 				boolean hasOutgoingTransition = false;
-				Iterator<Transition> transitionIt = state
-						.getOutgoingTransitions().iterator();
+				Iterator<Transition> transitionIt = state.getOutgoingTransitions().iterator();
 
 				while (transitionIt.hasNext() && !hasOutgoingTransition) {
 
 					Transition transition = transitionIt.next();
 
-					hasOutgoingTransition = STextValidationModelUtils
-							.isDefaultExitTransition(transition) ? true
-							: STextValidationModelUtils.isNamedExitTransition(
-									transition, exit.getName());
+					hasOutgoingTransition = STextValidationModelUtils.isDefaultExitTransition(transition) ? true
+							: STextValidationModelUtils.isNamedExitTransition(transition, exit.getName());
 				}
 				if (!hasOutgoingTransition) {
 					error(EXIT_UNUSED, exit, null, -1);
 				}
 			} else {
 				boolean hasOutgoingTransition = false;
-				Iterator<Transition> transitionIt = state
-						.getOutgoingTransitions().iterator();
+				Iterator<Transition> transitionIt = state.getOutgoingTransitions().iterator();
 				while (transitionIt.hasNext() && !hasOutgoingTransition) {
-					hasOutgoingTransition = STextValidationModelUtils
-							.isDefaultExitTransition(transitionIt.next());
+					hasOutgoingTransition = STextValidationModelUtils.isDefaultExitTransition(transitionIt.next());
 				}
 				if (!hasOutgoingTransition) {
 					error(EXIT_DEFAULT_UNUSED, exit, null, -1);
@@ -214,8 +205,7 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 					org.yakindu.sct.model.sgraph.State state = (org.yakindu.sct.model.sgraph.State) transition
 							.getTarget();
 					if (!state.isComposite()) {
-						warning(TRANSITION_ENTRY_SPEC_NOT_COMPOSITE,
-								transition, null, -1);
+						warning(TRANSITION_ENTRY_SPEC_NOT_COMPOSITE, transition, null, -1);
 					}
 				}
 			} else if (property instanceof ExitPointSpec) {
@@ -224,19 +214,14 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 					org.yakindu.sct.model.sgraph.State state = (org.yakindu.sct.model.sgraph.State) transition
 							.getSource();
 					if (!state.isComposite()) {
-						warning(TRANSITION_EXIT_SPEC_NOT_COMPOSITE, transition,
-								null, -1);
+						warning(TRANSITION_EXIT_SPEC_NOT_COMPOSITE, transition, null, -1);
 					} else {
 						// Validate an exit point is continued on one transition
 						// only.
 						for (Transition t : state.getOutgoingTransitions()) {
 							if (transition != t
-									&& STextValidationModelUtils
-											.isNamedExitTransition(t,
-													exitPointSpec
-															.getExitpoint())) {
-								warning(TRANSITION_EXIT_SPEC_ON_MULTIPLE_SIBLINGS,
-										transition, null, -1);
+									&& STextValidationModelUtils.isNamedExitTransition(t, exitPointSpec.getExitpoint())) {
+								warning(TRANSITION_EXIT_SPEC_ON_MULTIPLE_SIBLINGS, transition, null, -1);
 							}
 						}
 
@@ -244,22 +229,18 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 						// region
 
 						boolean hasExit = false;
-						Iterator<Region> regionIter = state.getRegions()
-								.iterator();
+						Iterator<Region> regionIter = state.getRegions().iterator();
 						while (regionIter.hasNext() && !hasExit) {
 
-							Iterator<Exit> exitIter = STextValidationModelUtils
-									.getExits(regionIter.next().eContents())
+							Iterator<Exit> exitIter = STextValidationModelUtils.getExits(regionIter.next().eContents())
 									.iterator();
 							while (exitIter.hasNext() && !hasExit) {
 								Exit exit = exitIter.next();
-								hasExit = exitPointSpec.getExitpoint().equals(
-										exit.getName());
+								hasExit = exitPointSpec.getExitpoint().equals(exit.getName());
 							}
 						}
 						if (!hasExit) {
-							error(TRANSITION_NOT_EXISTING_NAMED_EXIT_POINT,
-									transition, null, -1);
+							error(TRANSITION_NOT_EXISTING_NAMED_EXIT_POINT, transition, null, -1);
 						}
 
 					}
@@ -269,26 +250,21 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 	}
 
 	@Check(CheckType.FAST)
-	public void checkUnboundEntryPoints(
-			final org.yakindu.sct.model.sgraph.State state) {
+	public void checkUnboundEntryPoints(final org.yakindu.sct.model.sgraph.State state) {
 		if (state.isComposite()) {
-			final List<Transition>[] transitions = STextValidationModelUtils
-					.getEntrySpecSortedTransitions(state
-							.getIncomingTransitions());
+			final List<Transition>[] transitions = STextValidationModelUtils.getEntrySpecSortedTransitions(state
+					.getIncomingTransitions());
 			Map<Region, List<Entry>> regions = null;
 
 			// first list contains Transitions without entry spec
 			if (!transitions[0].isEmpty()) {
-				regions = STextValidationModelUtils
-						.getRegionsWithoutDefaultEntry(state.getRegions());
+				regions = STextValidationModelUtils.getRegionsWithoutDefaultEntry(state.getRegions());
 				if (!regions.isEmpty()) {
 					for (Transition transition : transitions[0]) {
-						error(TRANSITION_UNBOUND_DEFAULT_ENTRY_POINT,
-								transition, null, -1);
+						error(TRANSITION_UNBOUND_DEFAULT_ENTRY_POINT, transition, null, -1);
 					}
 					for (Region region : regions.keySet()) {
-						error(REGION_UNBOUND_DEFAULT_ENTRY_POINT, region, null,
-								-1);
+						error(REGION_UNBOUND_DEFAULT_ENTRY_POINT, region, null, -1);
 					}
 				}
 			}
@@ -296,8 +272,7 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 			// second list contains Transitions with entry spec
 			if (!transitions[1].isEmpty()) {
 				if (regions == null) {
-					regions = STextValidationModelUtils
-							.getRegionsWithoutDefaultEntry(state.getRegions());
+					regions = STextValidationModelUtils.getRegionsWithoutDefaultEntry(state.getRegions());
 				}
 				for (Transition transition : transitions[1]) {
 					boolean hasTargetEntry = true;
@@ -308,21 +283,18 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 							for (Region region : regions.keySet()) {
 								boolean hasEntry = false;
 								for (Entry entry : regions.get(region)) {
-									if (entry.getName().equals(
-											spec.getEntrypoint())) {
+									if (entry.getName().equals(spec.getEntrypoint())) {
 										hasEntry = true;
 										break;
 									}
 								}
 								if (!hasEntry) {
-									error(REGION_UNBOUND_NAMED_ENTRY_POINT
-											+ specName, region, null, -1);
+									error(REGION_UNBOUND_NAMED_ENTRY_POINT + specName, region, null, -1);
 									hasTargetEntry = false;
 								}
 							}
 							if (!hasTargetEntry) {
-								error(TRANSITION_UNBOUND_NAMED_ENTRY_POINT
-										+ specName, transition, null, -1);
+								error(TRANSITION_UNBOUND_NAMED_ENTRY_POINT + specName, transition, null, -1);
 							}
 						}
 					}
@@ -335,8 +307,7 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 	public void checkVariableDefinition(final VariableDefinition definition) {
 		try {
 			InferenceResult result = typeInferrer.inferType(definition);
-			if (result.getType() != null
-					&& typeSystem.isVoidType(result.getType())) {
+			if (result.getType() != null && typeSystem.isVoidType(result.getType())) {
 				error(VARIABLE_VOID_TYPE, null);
 			} else {
 				report(result, null);
@@ -360,8 +331,7 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 	}
 
 	@Check(CheckType.FAST)
-	public void checkOperationArguments_TypedElementReferenceExpression(
-			final ElementReferenceExpression call) {
+	public void checkOperationArguments_TypedElementReferenceExpression(final ElementReferenceExpression call) {
 		if (call.getReference() instanceof Operation) {
 			Operation operation = (Operation) call.getReference();
 			EList<Parameter> parameters = operation.getParameters();
@@ -377,18 +347,16 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 
 		final String name = getVariableName(exp);
 
-		List<AssignmentExpression> contents = EcoreUtil2.eAllOfType(exp,
-				AssignmentExpression.class);
+		List<AssignmentExpression> contents = EcoreUtil2.eAllOfType(exp, AssignmentExpression.class);
 		contents.remove(exp);
 
-		Iterable<AssignmentExpression> filter = Iterables.filter(contents,
-				new Predicate<AssignmentExpression>() {
-					public boolean apply(final AssignmentExpression ex) {
-						String variableName = getVariableName(ex);
-						return variableName.equals(name);
+		Iterable<AssignmentExpression> filter = Iterables.filter(contents, new Predicate<AssignmentExpression>() {
+			public boolean apply(final AssignmentExpression ex) {
+				String variableName = getVariableName(ex);
+				return variableName.equals(name);
 
-					}
-				});
+			}
+		});
 		if (Iterables.size(filter) > 0) {
 			error(ASSIGNMENT_EXPRESSION, null);
 		}
@@ -398,11 +366,9 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 		Expression varRef = exp.getVarRef();
 		if (varRef instanceof ElementReferenceExpression
 				&& ((ElementReferenceExpression) varRef).getReference() instanceof Property) {
-			Property reference = (Property) ((ElementReferenceExpression) varRef)
-					.getReference();
+			Property reference = (Property) ((ElementReferenceExpression) varRef).getReference();
 			return reference.getName();
-		} else if (varRef instanceof FeatureCall
-				&& ((FeatureCall) varRef).getFeature() instanceof Property) {
+		} else if (varRef instanceof FeatureCall && ((FeatureCall) varRef).getFeature() instanceof Property) {
 			Property reference = (Property) ((FeatureCall) varRef).getFeature();
 			return reference.getName();
 		}
@@ -415,8 +381,7 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 			return;
 		}
 		if (call.getFeature() instanceof Scope) {
-			error("A variable, event or operation is required",
-					StextPackage.Literals.FEATURE_CALL__FEATURE,
+			error("A variable, event or operation is required", StextPackage.Literals.FEATURE_CALL__FEATURE,
 					INSIGNIFICANT_INDEX, FEATURE_CALL_TO_SCOPE);
 		}
 	}
@@ -428,8 +393,8 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 		}
 		if (call.getReference() instanceof Scope) {
 			error("A variable, event or operation is required",
-					StextPackage.Literals.ELEMENT_REFERENCE_EXPRESSION__REFERENCE,
-					INSIGNIFICANT_INDEX, FEATURE_CALL_TO_SCOPE);
+					StextPackage.Literals.ELEMENT_REFERENCE_EXPRESSION__REFERENCE, INSIGNIFICANT_INDEX,
+					FEATURE_CALL_TO_SCOPE);
 		}
 	}
 
@@ -439,12 +404,9 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 			return;
 		}
 		try {
-			InferenceResult result = typeInferrer.inferType(trigger
-					.getGuardExpression());
-			if (result.getType() == null
-					|| !typeSystem.isBooleanType(result.getType())) {
-				error(GUARD_EXPRESSION,
-						StextPackage.Literals.REACTION_TRIGGER__GUARD_EXPRESSION);
+			InferenceResult result = typeInferrer.inferType(trigger.getGuardExpression());
+			if (result.getType() == null || !typeSystem.isBooleanType(result.getType())) {
+				error(GUARD_EXPRESSION, StextPackage.Literals.REACTION_TRIGGER__GUARD_EXPRESSION);
 			}
 			report(result, null);
 		} catch (IllegalArgumentException e) {
@@ -457,8 +419,7 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 	public void checkTimeEventSpecValueExpression(TimeEventSpec spec) {
 		try {
 			InferenceResult result = typeInferrer.inferType(spec.getValue());
-			if (result.getType() == null
-					|| !typeSystem.isIntegerType(result.getType())) {
+			if (result.getType() == null || !typeSystem.isIntegerType(result.getType())) {
 				error(TIME_EXPRESSION, null);
 			}
 			report(result, StextPackage.Literals.TIME_EVENT_SPEC__VALUE);
@@ -474,8 +435,8 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 			if (!(reactionTrigger.eContainer() instanceof LocalReaction)
 					&& (eventSpec instanceof EntryEvent || eventSpec instanceof ExitEvent)) {
 				error("entry and exit events are allowed as local reactions only.",
-						StextPackage.Literals.REACTION_TRIGGER__TRIGGERS,
-						INSIGNIFICANT_INDEX, LOCAL_REACTIONS_NOT_ALLOWED);
+						StextPackage.Literals.REACTION_TRIGGER__TRIGGERS, INSIGNIFICANT_INDEX,
+						LOCAL_REACTIONS_NOT_ALLOWED);
 			}
 		}
 	}
@@ -502,18 +463,15 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 	public void checkReactionEffectActions(ReactionEffect effect) {
 		for (Expression exp : effect.getActions()) {
 
-			if (!(exp instanceof AssignmentExpression)
-					&& !(exp instanceof EventRaisingExpression)) {
+			if (!(exp instanceof AssignmentExpression) && !(exp instanceof EventRaisingExpression)) {
 
 				if (exp instanceof FeatureCall) {
 					checkFeatureCallEffect((FeatureCall) exp);
 				} else if (exp instanceof ElementReferenceExpression) {
 					checkElementReferenceEffect((ElementReferenceExpression) exp);
 				} else {
-					error("Action has no effect.",
-							StextPackage.Literals.REACTION_EFFECT__ACTIONS,
-							effect.getActions().indexOf(exp),
-							FEATURE_CALL_HAS_NO_EFFECT);
+					error("Action has no effect.", StextPackage.Literals.REACTION_EFFECT__ACTIONS, effect.getActions()
+							.indexOf(exp), FEATURE_CALL_HAS_NO_EFFECT);
 				}
 
 			}
@@ -524,23 +482,17 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 		if (call.getFeature() != null && call.getFeature() instanceof Feature
 				&& !(call.getFeature() instanceof Operation)) {
 			if (call.getFeature() instanceof Property) {
-				error("Access to property '"
-						+ nameProvider.getFullyQualifiedName(call.getFeature())
-						+ "' has no effect.", call,
-						StextPackage.Literals.FEATURE_CALL__FEATURE,
-						INSIGNIFICANT_INDEX, FEATURE_CALL_HAS_NO_EFFECT);
+				error("Access to property '" + nameProvider.getFullyQualifiedName(call.getFeature())
+						+ "' has no effect.", call, StextPackage.Literals.FEATURE_CALL__FEATURE, INSIGNIFICANT_INDEX,
+						FEATURE_CALL_HAS_NO_EFFECT);
 			} else if (call.getFeature() instanceof Event) {
-				error("Access to event '"
-						+ nameProvider.getFullyQualifiedName(call.getFeature())
-						+ "' has no effect.", call,
-						StextPackage.Literals.FEATURE_CALL__FEATURE,
-						INSIGNIFICANT_INDEX, FEATURE_CALL_HAS_NO_EFFECT);
+				error("Access to event '" + nameProvider.getFullyQualifiedName(call.getFeature()) + "' has no effect.",
+						call, StextPackage.Literals.FEATURE_CALL__FEATURE, INSIGNIFICANT_INDEX,
+						FEATURE_CALL_HAS_NO_EFFECT);
 			} else {
-				error("Access to feature '"
-						+ nameProvider.getFullyQualifiedName(call.getFeature())
-						+ "' has no effect.", call,
-						StextPackage.Literals.FEATURE_CALL__FEATURE,
-						INSIGNIFICANT_INDEX, FEATURE_CALL_HAS_NO_EFFECT);
+				error("Access to feature '" + nameProvider.getFullyQualifiedName(call.getFeature())
+						+ "' has no effect.", call, StextPackage.Literals.FEATURE_CALL__FEATURE, INSIGNIFICANT_INDEX,
+						FEATURE_CALL_HAS_NO_EFFECT);
 			}
 		}
 	}
@@ -548,25 +500,16 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 	protected void checkElementReferenceEffect(ElementReferenceExpression refExp) {
 		if (!(refExp.getReference() instanceof Operation)) {
 			if (refExp.getReference() instanceof Property) {
-				error("Access to property '"
-						+ nameProvider.getFullyQualifiedName(refExp
-								.getReference()) + "' has no effect.",
-						refExp,
-						StextPackage.Literals.ELEMENT_REFERENCE_EXPRESSION__REFERENCE,
+				error("Access to property '" + nameProvider.getFullyQualifiedName(refExp.getReference())
+						+ "' has no effect.", refExp, StextPackage.Literals.ELEMENT_REFERENCE_EXPRESSION__REFERENCE,
 						INSIGNIFICANT_INDEX, FEATURE_CALL_HAS_NO_EFFECT);
 			} else if (refExp.getReference() instanceof Event) {
-				error("Access to event '"
-						+ nameProvider.getFullyQualifiedName(refExp
-								.getReference()) + "' has no effect.",
-						refExp,
-						StextPackage.Literals.ELEMENT_REFERENCE_EXPRESSION__REFERENCE,
+				error("Access to event '" + nameProvider.getFullyQualifiedName(refExp.getReference())
+						+ "' has no effect.", refExp, StextPackage.Literals.ELEMENT_REFERENCE_EXPRESSION__REFERENCE,
 						INSIGNIFICANT_INDEX, FEATURE_CALL_HAS_NO_EFFECT);
 			} else {
-				error("Access to feature '"
-						+ nameProvider.getFullyQualifiedName(refExp
-								.getReference()) + "' has no effect.",
-						refExp,
-						StextPackage.Literals.ELEMENT_REFERENCE_EXPRESSION__REFERENCE,
+				error("Access to feature '" + nameProvider.getFullyQualifiedName(refExp.getReference())
+						+ "' has no effect.", refExp, StextPackage.Literals.ELEMENT_REFERENCE_EXPRESSION__REFERENCE,
 						INSIGNIFICANT_INDEX, FEATURE_CALL_HAS_NO_EFFECT);
 			}
 		}
@@ -574,15 +517,11 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 
 	@Check(CheckType.FAST)
 	public void checkEventDefinition(EventDefinition event) {
-		if (event.eContainer() instanceof InterfaceScope
-				&& event.getDirection() == Direction.LOCAL) {
-			error(LOCAL_DECLARATIONS,
-					StextPackage.Literals.EVENT_DEFINITION__DIRECTION);
+		if (event.eContainer() instanceof InterfaceScope && event.getDirection() == Direction.LOCAL) {
+			error(LOCAL_DECLARATIONS, StextPackage.Literals.EVENT_DEFINITION__DIRECTION);
 		}
-		if (event.eContainer() instanceof InternalScope
-				&& event.getDirection() != Direction.LOCAL) {
-			error(IN_OUT_DECLARATIONS,
-					StextPackage.Literals.EVENT_DEFINITION__DIRECTION);
+		if (event.eContainer() instanceof InternalScope && event.getDirection() != Direction.LOCAL) {
+			error(IN_OUT_DECLARATIONS, StextPackage.Literals.EVENT_DEFINITION__DIRECTION);
 		}
 	}
 
@@ -591,17 +530,32 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 		List<InterfaceScope> defaultInterfaces = new LinkedList<InterfaceScope>();
 
 		for (Scope scope : statechart.getScopes()) {
-			if (scope instanceof InterfaceScope
-					&& ((InterfaceScope) scope).getName() == null) {
+			if (scope instanceof InterfaceScope && ((InterfaceScope) scope).getName() == null) {
 				defaultInterfaces.add((InterfaceScope) scope);
 			}
 		}
 		if (defaultInterfaces.size() > 1) {
 			for (InterfaceScope scope : defaultInterfaces) {
-				error(ONLY_ONE_INTERFACE, scope, grammarAccess
-						.getInterfaceScopeAccess().getInterfaceKeyword_1(),
-						ValidationMessageAcceptor.INSIGNIFICANT_INDEX,
-						ONLY_ONE_INTERFACE);
+				error(ONLY_ONE_INTERFACE, scope, grammarAccess.getInterfaceScopeAccess().getInterfaceKeyword_1(),
+						ValidationMessageAcceptor.INSIGNIFICANT_INDEX, ONLY_ONE_INTERFACE);
+			}
+		}
+	}
+
+	@Check(CheckType.FAST)
+	public void checkInterfaceScope(Expression expression) {
+		// Only executed in the context ob conditional expressions: TODO: Move
+		// to separate validator
+		if (expression.eContainer() == null) {
+			try {
+				InferenceResult result = typeInferrer.inferType(expression);
+				if (result.getType() == null || !typeSystem.isBooleanType(result.getType())) {
+					error(CONDITIONAL_EXPRESSION, null);
+				}
+				report(result, null);
+			} catch (IllegalArgumentException e) {
+				// ignore unknown literals here, as this also happens when a
+				// linking problem occurred, which is handled in other locations
 			}
 		}
 	}
@@ -616,22 +570,19 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 			}
 		}
 		if (!found)
-			warning(CHOICE_ONE_OUTGOING_DEFAULT_TRANSITION,
-					SGraphPackage.Literals.VERTEX__OUTGOING_TRANSITIONS);
+			warning(CHOICE_ONE_OUTGOING_DEFAULT_TRANSITION, SGraphPackage.Literals.VERTEX__OUTGOING_TRANSITIONS);
 	}
 
 	protected boolean isDefault(Trigger trigger) {
 
 		return trigger == null
 				|| trigger instanceof DefaultTrigger
-				|| ((trigger instanceof ReactionTrigger)
-						&& ((ReactionTrigger) trigger).getTriggers().size() == 0 && ((ReactionTrigger) trigger)
+				|| ((trigger instanceof ReactionTrigger) && ((ReactionTrigger) trigger).getTriggers().size() == 0 && ((ReactionTrigger) trigger)
 						.getGuardExpression() == null);
 	}
 
 	@Override
-	protected String getCurrentLanguage(Map<Object, Object> context,
-			EObject eObject) {
+	protected String getCurrentLanguage(Map<Object, Object> context, EObject eObject) {
 		Resource eResource = eObject.eResource();
 		if (eResource instanceof XtextResource) {
 			return super.getCurrentLanguage(context, eObject);
@@ -641,23 +592,19 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 		return "";
 	}
 
-	protected void error(String message, EObject source, Keyword keyword,
-			int index, String code) {
+	protected void error(String message, EObject source, Keyword keyword, int index, String code) {
 		final String[] issueData = null;
 		ICompositeNode rootNode = NodeModelUtils.findActualNodeFor(source);
 		if (rootNode != null) {
-			INode child = findNode(source, false, rootNode, keyword,
-					new int[] { index });
+			INode child = findNode(source, false, rootNode, keyword, new int[] { index });
 			if (child != null) {
 				int offset = child.getTotalOffset();
 				int length = child.getTotalLength();
-				getMessageAcceptor().acceptError(message, source, offset,
-						length, code, issueData);
+				getMessageAcceptor().acceptError(message, source, offset, length, code, issueData);
 				return;
 			}
 		}
-		error(message, source, (EStructuralFeature) null,
-				ValidationMessageAcceptor.INSIGNIFICANT_INDEX, code);
+		error(message, source, (EStructuralFeature) null, ValidationMessageAcceptor.INSIGNIFICANT_INDEX, code);
 	}
 
 	protected void report(InferenceResult result, EStructuralFeature feature) {
@@ -669,8 +616,7 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 
 	}
 
-	private INode findNode(EObject source, boolean sourceFound, INode root,
-			Keyword keyword, int[] index) {
+	private INode findNode(EObject source, boolean sourceFound, INode root, Keyword keyword, int[] index) {
 		if (sourceFound && root.getSemanticElement() != source) {
 			return null;
 		}
@@ -681,9 +627,7 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 		// .equals or == does not work because sub grammars use their own
 		// Modules with custom
 		// grammarAccess instance and .equals is not overwritten.
-		if (grammarElement instanceof Keyword
-				&& keyword.getValue().equals(
-						((Keyword) grammarElement).getValue())) {
+		if (grammarElement instanceof Keyword && keyword.getValue().equals(((Keyword) grammarElement).getValue())) {
 			if (index[0] != INSIGNIFICANT_INDEX) {
 				index[0]--;
 			}
@@ -694,8 +638,7 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 		if (root instanceof ICompositeNode) {
 			ICompositeNode node = (ICompositeNode) root;
 			for (INode child : node.getChildren()) {
-				INode result = findNode(source, sourceFound, child, keyword,
-						index);
+				INode result = findNode(source, sourceFound, child, keyword, index);
 				if (result != null) {
 					return result;
 				}

+ 11 - 5
plugins/org.yakindu.sct.simulation.ui/src/org/yakindu/sct/simulation/ui/breakpoints/SCTBreakpointDetailPane.java

@@ -15,6 +15,7 @@ import org.eclipse.draw2d.ColorConstants;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.jface.bindings.keys.KeyStroke;
 import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.swt.SWT;
@@ -35,6 +36,7 @@ import org.yakindu.sct.simulation.core.breakpoints.SCTBreakpoint;
 import org.yakindu.sct.ui.editor.extensions.ExpressionLanguageProviderExtensions;
 import org.yakindu.sct.ui.editor.extensions.IExpressionLanguageProvider;
 
+import de.itemis.xtext.utils.jface.fieldassist.CompletionProposalAdapter;
 import de.itemis.xtext.utils.jface.viewers.ContextElementAdapter;
 import de.itemis.xtext.utils.jface.viewers.ContextElementAdapter.IContextElementProvider;
 import de.itemis.xtext.utils.jface.viewers.StyledTextXtextAdapter;
@@ -92,16 +94,20 @@ public class SCTBreakpointDetailPane implements IDetailPane, IContextElementProv
 
 	protected void createTextArea(Composite parent) {
 		text = new StyledText(parent, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
-		text.addFocusListener(new FocusAdapter() {
-			public void focusLost(FocusEvent e) {
-				breakpoint.setExpression(text.getText());
-			}
-		});
 		IExpressionLanguageProvider provider = ExpressionLanguageProviderExtensions.getLanguageProvider(
 				BREAKPOINT_CONDITION, "sct");
 		adapter = new StyledTextXtextAdapter(provider.getInjector());
 		adapter.getFakeResourceContext().getFakeResource().eAdapters().add(new ContextElementAdapter(this));
 		adapter.adapt(text);
+		final CompletionProposalAdapter completionAdapter = new CompletionProposalAdapter(text,
+				adapter.getContentAssistant(), KeyStroke.getInstance(SWT.CTRL, SWT.SPACE), null);
+		text.addFocusListener(new FocusAdapter() {
+			public void focusLost(FocusEvent e) {
+				if (!completionAdapter.isProposalPopupOpen()) {
+					breakpoint.setExpression(text.getText());
+				}
+			}
+		});
 		GridDataFactory.fillDefaults().grab(true, true).applyTo(text);
 	}