diff --git a/plugins/core/hu.bme.mit.gamma.activity.language/src/hu/bme/mit/gamma/activity/language/scoping/ActivityLanguageScopeProvider.java b/plugins/core/hu.bme.mit.gamma.activity.language/src/hu/bme/mit/gamma/activity/language/scoping/ActivityLanguageScopeProvider.java index 167b7d65c..6bf4f9cb5 100644 --- a/plugins/core/hu.bme.mit.gamma.activity.language/src/hu/bme/mit/gamma/activity/language/scoping/ActivityLanguageScopeProvider.java +++ b/plugins/core/hu.bme.mit.gamma.activity.language/src/hu/bme/mit/gamma/activity/language/scoping/ActivityLanguageScopeProvider.java @@ -3,6 +3,18 @@ */ package hu.bme.mit.gamma.activity.language.scoping; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.xtext.scoping.IScope; +import org.eclipse.xtext.scoping.Scopes; + +import hu.bme.mit.gamma.activity.derivedfeatures.ActivityModelDerivedFeatures; +import hu.bme.mit.gamma.activity.model.ActivityDeclaration; +import hu.bme.mit.gamma.activity.model.ActivityDefinition; +import hu.bme.mit.gamma.activity.model.ActivityModelPackage; +import hu.bme.mit.gamma.activity.model.InsidePinReference; +import hu.bme.mit.gamma.activity.model.OutsidePinReference; +import hu.bme.mit.gamma.activity.model.PinReference; /** * This class contains custom scoping description. @@ -11,5 +23,43 @@ * on how and when to use it. */ public class ActivityLanguageScopeProvider extends AbstractActivityLanguageScopeProvider { + + @Override + public IScope getScope(final EObject context, final EReference reference) { + try { + if (context instanceof PinReference) { + + if (context instanceof InsidePinReference) { + ActivityDeclaration declaration = ActivityModelDerivedFeatures.getContainingActivityDeclaration(context); + + return Scopes.scopeFor(declaration.getPins()); + } + else { // instanceof OutsidePinReference + if (reference == ActivityModelPackage.Literals.OUTSIDE_PIN_REFERENCE__ACTION_NODE) { + ActivityDefinition definition = ActivityModelDerivedFeatures.getContainingActivityDefinition(context); + + return Scopes.scopeFor(definition.getActivityNodes()); + } + if (reference == ActivityModelPackage.Literals.OUTPUT_PIN_REFERENCE__OUTPUT_PIN) { + ActivityDeclaration declaration = ActivityModelDerivedFeatures.getReferencedActivityDeclaration((OutsidePinReference)context); + + return Scopes.scopeFor(declaration.getPins()); + } + if (reference == ActivityModelPackage.Literals.INPUT_PIN_REFERENCE__INPUT_PIN) { + ActivityDeclaration declaration = ActivityModelDerivedFeatures.getReferencedActivityDeclaration((OutsidePinReference)context); + + return Scopes.scopeFor(declaration.getPins()); + } + + } + + } + } catch (Exception e) { + e.printStackTrace(); + } + + return super.getScope(context, reference); + } + } diff --git a/plugins/core/hu.bme.mit.gamma.activity.language/src/hu/bme/mit/gamma/activity/language/validation/ActivityLanguageValidator.java b/plugins/core/hu.bme.mit.gamma.activity.language/src/hu/bme/mit/gamma/activity/language/validation/ActivityLanguageValidator.java index f82dffe5f..b5cfdc62b 100644 --- a/plugins/core/hu.bme.mit.gamma.activity.language/src/hu/bme/mit/gamma/activity/language/validation/ActivityLanguageValidator.java +++ b/plugins/core/hu.bme.mit.gamma.activity.language/src/hu/bme/mit/gamma/activity/language/validation/ActivityLanguageValidator.java @@ -3,6 +3,10 @@ */ package hu.bme.mit.gamma.activity.language.validation; +import org.eclipse.xtext.validation.Check; + +import hu.bme.mit.gamma.activity.util.ActivityModelValidator; +import hu.bme.mit.gamma.expression.model.NamedElement; /** * This class contains custom validation rules. @@ -11,15 +15,17 @@ */ public class ActivityLanguageValidator extends AbstractActivityLanguageValidator { -// public static final String INVALID_NAME = "invalidName"; -// -// @Check -// public void checkGreetingStartsWithCapital(Greeting greeting) { -// if (!Character.isUpperCase(greeting.getName().charAt(0))) { -// warning("Name should start with a capital", -// ActivityLanguagePackage.Literals.GREETING__NAME, -// INVALID_NAME); -// } -// } + protected ActivityModelValidator activityModelValidator = ActivityModelValidator.INSTANCE; + + public ActivityLanguageValidator() { + super.expressionModelValidator = activityModelValidator; + super.actionModelValidator = activityModelValidator; + } + + @Check + @Override + public void checkNameUniqueness(NamedElement element) { + handleValidationResultMessage(activityModelValidator.checkNameUniqueness(element)); + } } diff --git a/plugins/core/hu.bme.mit.gamma.activity.model/META-INF/MANIFEST.MF b/plugins/core/hu.bme.mit.gamma.activity.model/META-INF/MANIFEST.MF index cebf84291..fd806f8f4 100644 --- a/plugins/core/hu.bme.mit.gamma.activity.model/META-INF/MANIFEST.MF +++ b/plugins/core/hu.bme.mit.gamma.activity.model/META-INF/MANIFEST.MF @@ -13,6 +13,8 @@ Bundle-ActivationPolicy: lazy Bundle-Vendor: BME-FTSRG Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-11 -Export-Package: hu.bme.mit.gamma.activity.model, +Export-Package: hu.bme.mit.gamma.activity.derivedfeatures, + hu.bme.mit.gamma.activity.model, hu.bme.mit.gamma.activity.model.impl, - hu.bme.mit.gamma.activity.model.util + hu.bme.mit.gamma.activity.model.util, + hu.bme.mit.gamma.activity.util diff --git a/plugins/core/hu.bme.mit.gamma.activity.model/src/hu/bme/mit/gamma/activity/derivedfeatures/ActivityModelDerivedFeatures.java b/plugins/core/hu.bme.mit.gamma.activity.model/src/hu/bme/mit/gamma/activity/derivedfeatures/ActivityModelDerivedFeatures.java new file mode 100644 index 000000000..4cf3d2397 --- /dev/null +++ b/plugins/core/hu.bme.mit.gamma.activity.model/src/hu/bme/mit/gamma/activity/derivedfeatures/ActivityModelDerivedFeatures.java @@ -0,0 +1,44 @@ +package hu.bme.mit.gamma.activity.derivedfeatures; + +import org.eclipse.emf.ecore.EObject; + +import hu.bme.mit.gamma.action.derivedfeatures.ActionModelDerivedFeatures; +import hu.bme.mit.gamma.activity.model.ActivityDeclaration; +import hu.bme.mit.gamma.activity.model.ActivityDeclarationReference; +import hu.bme.mit.gamma.activity.model.ActivityDefinition; +import hu.bme.mit.gamma.activity.model.InlineActivityDeclaration; +import hu.bme.mit.gamma.activity.model.NamedActivityDeclarationReference; +import hu.bme.mit.gamma.activity.model.OutsidePinReference; + +public class ActivityModelDerivedFeatures extends ActionModelDerivedFeatures { + + public static ActivityDeclaration getContainingActivityDeclaration(EObject element) { + if (element instanceof ActivityDeclaration) { + return (ActivityDeclaration)element; + } + + return getContainingActivityDeclaration(element.eContainer()); + } + + public static ActivityDefinition getContainingActivityDefinition(EObject element) { + if (element instanceof ActivityDefinition) { + return (ActivityDefinition)element; + } + + return getContainingActivityDefinition(element.eContainer()); + } + + public static ActivityDeclaration getReferencedActivityDeclaration(OutsidePinReference reference) { + ActivityDeclarationReference declReference = reference.getActionNode().getActivityDeclarationReference(); + + if (declReference instanceof InlineActivityDeclaration) { + return (InlineActivityDeclaration)declReference; + } + if (declReference instanceof NamedActivityDeclarationReference) { + return ((NamedActivityDeclarationReference)declReference).getNamedActivityDeclaration(); + } + + return null; + } + +} diff --git a/plugins/core/hu.bme.mit.gamma.activity.model/src/hu/bme/mit/gamma/activity/util/ActivityExpressionTypeDeterminator.java b/plugins/core/hu.bme.mit.gamma.activity.model/src/hu/bme/mit/gamma/activity/util/ActivityExpressionTypeDeterminator.java new file mode 100644 index 000000000..3fb201ebb --- /dev/null +++ b/plugins/core/hu.bme.mit.gamma.activity.model/src/hu/bme/mit/gamma/activity/util/ActivityExpressionTypeDeterminator.java @@ -0,0 +1,37 @@ +package hu.bme.mit.gamma.activity.util; + +import hu.bme.mit.gamma.activity.model.InputPinReference; +import hu.bme.mit.gamma.activity.model.OutputPinReference; +import hu.bme.mit.gamma.activity.model.Pin; +import hu.bme.mit.gamma.activity.model.PinReference; +import hu.bme.mit.gamma.expression.model.Expression; +import hu.bme.mit.gamma.expression.util.ExpressionType; +import hu.bme.mit.gamma.expression.util.ExpressionTypeDeterminator; + +public class ActivityExpressionTypeDeterminator extends ExpressionTypeDeterminator { + // Singleton + public static final ActivityExpressionTypeDeterminator INSTANCE = new ActivityExpressionTypeDeterminator(); + protected ActivityExpressionTypeDeterminator() {} + // + + @Override + public ExpressionType getType(Expression expression) { + if (expression instanceof PinReference) { + return getType((PinReference)expression); + } + + return super.getType(expression); + } + + public ExpressionType getType(PinReference reference) { + Pin pin; + + if (reference instanceof InputPinReference) { + pin = ((InputPinReference)reference).getInputPin(); + } else { + pin = ((OutputPinReference)reference).getOutputPin(); + } + + return transform(pin.getType()); + } +} diff --git a/plugins/core/hu.bme.mit.gamma.activity.model/src/hu/bme/mit/gamma/activity/util/ActivityModelValidator.java b/plugins/core/hu.bme.mit.gamma.activity.model/src/hu/bme/mit/gamma/activity/util/ActivityModelValidator.java new file mode 100644 index 000000000..e0261c446 --- /dev/null +++ b/plugins/core/hu.bme.mit.gamma.activity.model/src/hu/bme/mit/gamma/activity/util/ActivityModelValidator.java @@ -0,0 +1,67 @@ +package hu.bme.mit.gamma.activity.util; + +import java.util.ArrayList; +import java.util.Collection; + +import hu.bme.mit.gamma.action.util.ActionModelValidator; +import hu.bme.mit.gamma.activity.model.ActivityDeclaration; +import hu.bme.mit.gamma.activity.model.ActivityDefinition; +import hu.bme.mit.gamma.activity.model.ActivityNode; +import hu.bme.mit.gamma.activity.model.ActivityPackage; +import hu.bme.mit.gamma.activity.model.NamedActivityDeclaration; +import hu.bme.mit.gamma.activity.model.Pin; +import hu.bme.mit.gamma.expression.model.ExpressionModelPackage; +import hu.bme.mit.gamma.expression.model.NamedElement; + +public class ActivityModelValidator extends ActionModelValidator { + // Singleton + public static final ActivityModelValidator INSTANCE = new ActivityModelValidator(); + protected ActivityModelValidator() { + super.typeDeterminator = ActivityExpressionTypeDeterminator.INSTANCE; // PinReference + } + // + + @Override + public Collection checkNameUniqueness(NamedElement element) { + String name = element.getName(); + + if (element instanceof ActivityNode) { + ActivityDefinition activityDefinition = ecoreUtil.getContainerOfType(element, ActivityDefinition.class); + + return checkDirectNames(activityDefinition.getActivityNodes(), name); + } + if (element instanceof Pin) { + ActivityDeclaration activityDeclaration = ecoreUtil.getContainerOfType(element, ActivityDeclaration.class); + + return checkDirectNames(activityDeclaration.getPins(), name); + } + if (element instanceof NamedActivityDeclaration) { + ActivityPackage activityPackage = ecoreUtil.getContainerOfType(element, ActivityPackage.class); + + return checkDirectNames(activityPackage.getNamedActivityDeclarations(), name); + } + + return super.checkNameUniqueness(element); + } + + public Collection checkDirectNames(Collection elements, String name) { + int nameCount = 0; + + Collection validationResultMessages = new ArrayList(); + + for (T element : elements) { + if (element instanceof NamedElement) { + if (name.equals(((NamedElement)element).getName())) { + ++nameCount; + } + if (nameCount > 1) { + validationResultMessages.add(new ValidationResultMessage(ValidationResult.ERROR, + "In a Gamma model, these identifiers must be unique in the same context.", + new ReferenceInfo(ExpressionModelPackage.Literals.NAMED_ELEMENT__NAME, null))); + } + } + } + return validationResultMessages; + } + +} \ No newline at end of file