blob: 320cfb9287a9ed7539c45798862c0eec949aefae [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2013 E.D.Willink 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:
* E.D.Willink - Initial API and implementation
*******************************************************************************/
package org.eclipse.ocl.xtext.base.as2cs;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.CollectionType;
import org.eclipse.ocl.pivot.Constraint;
import org.eclipse.ocl.pivot.DataType;
import org.eclipse.ocl.pivot.Detail;
import org.eclipse.ocl.pivot.Element;
import org.eclipse.ocl.pivot.EnumerationLiteral;
import org.eclipse.ocl.pivot.ExpressionInOCL;
import org.eclipse.ocl.pivot.Import;
import org.eclipse.ocl.pivot.LanguageExpression;
import org.eclipse.ocl.pivot.Model;
import org.eclipse.ocl.pivot.Namespace;
import org.eclipse.ocl.pivot.Operation;
import org.eclipse.ocl.pivot.Parameter;
import org.eclipse.ocl.pivot.PivotPackage;
import org.eclipse.ocl.pivot.PrimitiveType;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.TemplateParameter;
import org.eclipse.ocl.pivot.TemplateSignature;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.util.AbstractExtendingVisitor;
import org.eclipse.ocl.pivot.util.Visitable;
import org.eclipse.ocl.xtext.base.utilities.BaseCSResource;
import org.eclipse.ocl.xtext.basecs.AnnotationCS;
import org.eclipse.ocl.xtext.basecs.AttributeCS;
import org.eclipse.ocl.xtext.basecs.BaseCSFactory;
import org.eclipse.ocl.xtext.basecs.BaseCSPackage;
import org.eclipse.ocl.xtext.basecs.ClassCS;
import org.eclipse.ocl.xtext.basecs.ConstraintCS;
import org.eclipse.ocl.xtext.basecs.DataTypeCS;
import org.eclipse.ocl.xtext.basecs.DetailCS;
import org.eclipse.ocl.xtext.basecs.ElementCS;
import org.eclipse.ocl.xtext.basecs.EnumerationCS;
import org.eclipse.ocl.xtext.basecs.EnumerationLiteralCS;
import org.eclipse.ocl.xtext.basecs.ImportCS;
import org.eclipse.ocl.xtext.basecs.ModelElementCS;
import org.eclipse.ocl.xtext.basecs.ModelElementRefCS;
import org.eclipse.ocl.xtext.basecs.OperationCS;
import org.eclipse.ocl.xtext.basecs.PackageCS;
import org.eclipse.ocl.xtext.basecs.ParameterCS;
import org.eclipse.ocl.xtext.basecs.PathNameCS;
import org.eclipse.ocl.xtext.basecs.ReferenceCS;
import org.eclipse.ocl.xtext.basecs.RootPackageCS;
import org.eclipse.ocl.xtext.basecs.SpecificationCS;
import org.eclipse.ocl.xtext.basecs.StructuralFeatureCS;
import org.eclipse.ocl.xtext.basecs.StructuredClassCS;
import org.eclipse.ocl.xtext.basecs.TemplateParameterCS;
import org.eclipse.ocl.xtext.basecs.TemplateSignatureCS;
import org.eclipse.ocl.xtext.basecs.TypeParameterCS;
import org.eclipse.ocl.xtext.basecs.TypedRefCS;
public class BaseDeclarationVisitor extends AbstractExtendingVisitor<ElementCS, AS2CSConversion>
{
public BaseDeclarationVisitor(@NonNull AS2CSConversion context) {
super(context); // NB this class is stateless since separate instances exist per CS package
}
/**
* After the visit to all elements, perform any post-processing such as installing imports.
*/
public void postProcess(@NonNull BaseCSResource csResource, @NonNull Map<Namespace, List<String>> importedNamespaces) {}
@Override
public ElementCS visitAnnotation(@NonNull org.eclipse.ocl.pivot.Annotation object) {
AnnotationCS csElement = context.refreshNamedElement(AnnotationCS.class, BaseCSPackage.Literals.ANNOTATION_CS, object);
context.refreshList(csElement.getOwnedContents(), context.visitDeclarations(ModelElementCS.class, object.getOwnedContents(), null));
context.refreshList(csElement.getOwnedDetails(), context.visitDeclarations(DetailCS.class, object.getOwnedDetails(), null));
List<Element> references = object.getReferences();
if (references.size() > 0) {
List<ModelElementRefCS> csReferences = new ArrayList<ModelElementRefCS>(references.size());
for (Element reference : references) {
if (reference != null) {
ModelElementRefCS csRef = BaseCSFactory.eINSTANCE.createModelElementRefCS();
@SuppressWarnings("null") @NonNull PathNameCS csPathName = BaseCSFactory.eINSTANCE.createPathNameCS();
csRef.setOwnedPathName(csPathName);
context.refreshPathName(csPathName, reference, context.getScope());
csReferences.add(csRef);
}
}
context.refreshList(csElement.getOwnedReferences(), csReferences);
}
else {
csElement.getOwnedReferences().clear();
}
return csElement;
}
@Override
public ElementCS visitClass(@NonNull org.eclipse.ocl.pivot.Class object) {
org.eclipse.ocl.pivot.Class savedScope = context.setScope(object);
StructuredClassCS csElement = context.refreshClassifier(StructuredClassCS.class, BaseCSPackage.Literals.STRUCTURED_CLASS_CS, object);
context.refreshList(csElement.getOwnedProperties(), context.visitDeclarations(StructuralFeatureCS.class, object.getOwnedProperties(),
new AS2CS.Predicate<Property>()
{
@Override
public boolean filter(@NonNull Property element) {
return !element.isImplicit();
}
}));
context.refreshList(csElement.getOwnedOperations(), context.visitDeclarations(OperationCS.class, object.getOwnedOperations(), null));
final Type oclElementType = context.getStandardLibrary().getOclElementType();
context.refreshList(csElement.getOwnedSuperTypes(), context.visitReferences(TypedRefCS.class, object.getSuperClasses(),
new AS2CS.Predicate<Type>()
{
@Override
public boolean filter(@NonNull Type element) {
return element != oclElementType;
}
}));
csElement.setIsAbstract(object.isAbstract());
csElement.setIsInterface(object.isInterface());
context.setScope(savedScope);
return csElement;
}
// @Override
// public ElementCS visitComment(Comment object) {
// ParameterCS pivotElement = context.refreshNamedElement(ParameterCS.class, BaseCSPackage.Literals.COMMENT_CS, object);
// return null;
// }
@Override
public ElementCS visitConstraint(@NonNull Constraint object) {
ConstraintCS csElement = context.refreshNamedElement(ConstraintCS.class, BaseCSPackage.Literals.CONSTRAINT_CS, object);
LanguageExpression specification = object.getOwnedSpecification();
csElement.setOwnedSpecification(specification != null ? context.visitDeclaration(SpecificationCS.class, specification) : null);
return csElement;
}
@Override
public ElementCS visitDataType(@NonNull DataType object) {
DataTypeCS csElement = context.refreshClassifier(DataTypeCS.class, BaseCSPackage.Literals.DATA_TYPE_CS, object);
csElement.setIsSerializable(object.isSerializable());
return csElement;
}
@Override
public ElementCS visitDetail(@NonNull Detail object) {
DetailCS csElement = context.refreshNamedElement(DetailCS.class, BaseCSPackage.Literals.DETAIL_CS, object);
List<String> values = csElement.getValues();
values.clear();
values.addAll(object.getValues());
return csElement;
}
@Override
public ElementCS visitEnumeration(@NonNull org.eclipse.ocl.pivot.Enumeration object) {
EnumerationCS csElement = context.refreshClassifier(EnumerationCS.class, BaseCSPackage.Literals.ENUMERATION_CS, object);
context.refreshList(csElement.getOwnedLiterals(), context.visitDeclarations(EnumerationLiteralCS.class, object.getOwnedLiterals(), null));
csElement.setIsSerializable(object.isSerializable());
return csElement;
}
@Override
public ElementCS visitEnumerationLiteral(@NonNull EnumerationLiteral object) {
EnumerationLiteralCS csElement = context.refreshNamedElement(EnumerationLiteralCS.class,
BaseCSPackage.Literals.ENUMERATION_LITERAL_CS, object);
if (object.eIsSet(PivotPackage.Literals.ENUMERATION_LITERAL__VALUE)) {
csElement.setValue(object.getValue().intValue());
}
else {
csElement.eUnset(BaseCSPackage.Literals.ENUMERATION_LITERAL_CS__VALUE);
}
return csElement;
}
@Override
public ElementCS visitExpressionInOCL(@NonNull ExpressionInOCL object) {
SpecificationCS csElement = context.refreshElement(SpecificationCS.class, BaseCSPackage.Literals.SPECIFICATION_CS, object);
String body = object.getBody();
csElement.setExprString(body);
return csElement;
}
@Override
public ElementCS visitImport(@NonNull Import object) {
Namespace importedNamespace = object.getImportedNamespace();
if (importedNamespace != null) {
context.importNamespace(importedNamespace, object.getName());
}
return null;
}
@Override
public ElementCS visitModel(@NonNull Model object) {
RootPackageCS csElement = context.refreshElement(RootPackageCS.class, BaseCSPackage.Literals.ROOT_PACKAGE_CS, object);
context.refreshList(csElement.getOwnedPackages(), context.visitDeclarations(PackageCS.class, object.getOwnedPackages(), null));
context.visitDeclarations(ImportCS.class, object.getOwnedImports(), null);
return csElement;
}
@Override
public ElementCS visitOperation(@NonNull Operation object) {
OperationCS csElement = context.refreshTypedElement(OperationCS.class, BaseCSPackage.Literals.OPERATION_CS, object);
TemplateSignature ownedTemplateSignature = object.getOwnedSignature();
csElement.setOwnedSignature(context.visitDeclaration(TemplateSignatureCS.class, ownedTemplateSignature));
context.refreshList(csElement.getOwnedParameters(), context.visitDeclarations(ParameterCS.class, object.getOwnedParameters(), null));
context.refreshList(csElement.getOwnedExceptions(), context.visitReferences(TypedRefCS.class, object.getRaisedExceptions(), null));
//
context.refreshList(csElement.getOwnedPreconditions(), context.visitDeclarations(ConstraintCS.class, object.getOwnedPreconditions(), null));
List<LanguageExpression> bodyExpressions = object.getBodyExpression() != null ? Collections.singletonList(object.getBodyExpression()) : Collections.<LanguageExpression>emptyList();
context.refreshList(csElement.getOwnedBodyExpressions(), context.visitDeclarations(SpecificationCS.class, bodyExpressions, null));
context.refreshList(csElement.getOwnedPostconditions(), context.visitDeclarations(ConstraintCS.class, object.getOwnedPostconditions(), null));
return csElement;
}
@Override
public ElementCS visitPackage(@NonNull org.eclipse.ocl.pivot.Package object) {
PackageCS csPackage = context.refreshNamedElement(PackageCS.class, BaseCSPackage.Literals.PACKAGE_CS, object);
context.refreshList(csPackage.getOwnedClasses(), context.visitDeclarations(ClassCS.class, object.getOwnedClasses(), null));
csPackage.setNsPrefix(object.getNsPrefix());
csPackage.setNsURI(object.getURI());
context.refreshList(csPackage.getOwnedPackages(), context.visitDeclarations(PackageCS.class, object.getOwnedPackages(), null));
return csPackage;
}
@Override
public ElementCS visitParameter(@NonNull Parameter object) {
ParameterCS csElement = context.refreshTypedElement(ParameterCS.class, BaseCSPackage.Literals.PARAMETER_CS, object);
return csElement;
}
@Override
public @Nullable ElementCS visitPrimitiveType(@NonNull PrimitiveType object) {
DataTypeCS csElement = context.refreshClassifier(DataTypeCS.class, BaseCSPackage.Literals.DATA_TYPE_CS, object);
csElement.setIsPrimitive(true);
csElement.setIsSerializable(object.isSerializable());
return csElement;
}
@Override
public ElementCS visitProperty(@NonNull Property object) {
StructuralFeatureCS csElement;
Type type = object.getType();
if (type instanceof CollectionType) {
type = ((CollectionType)type).getElementType();
}
if (type instanceof DataType) {
AttributeCS csAttribute = context.refreshStructuralFeature(AttributeCS.class, BaseCSPackage.Literals.ATTRIBUTE_CS, object);
csAttribute.setIsId(object.isID());
csElement = csAttribute;
}
else {
ReferenceCS csReference = context.refreshStructuralFeature(ReferenceCS.class, BaseCSPackage.Literals.REFERENCE_CS, object);
csReference.setIsComposes(object.isComposite());
csReference.setIsResolve(object.isResolveProxies());
Property opposite = object.getOpposite();
if (opposite != null) {
if (!opposite.isImplicit()) {
csReference.setReferredOpposite(opposite);
}
else {
// FIXME BUG 377626
}
}
context.refreshList(csReference.getReferredKeys(), object.getKeys());
csElement = csReference;
}
List<LanguageExpression> defaultExpressions = object.getOwnedExpression() != null ? Collections.singletonList(object.getOwnedExpression()) : Collections.<LanguageExpression>emptyList();
context.refreshList(csElement.getOwnedDefaultExpressions(), context.visitDeclarations(SpecificationCS.class, defaultExpressions, null));
return csElement;
}
@Override
public ElementCS visitTemplateSignature(@NonNull TemplateSignature object) {
TemplateSignatureCS csElement = context.refreshElement(TemplateSignatureCS.class, BaseCSPackage.Literals.TEMPLATE_SIGNATURE_CS, object);
context.refreshList(csElement.getOwnedParameters(), context.visitDeclarations(TemplateParameterCS.class, object.getOwnedParameters(), null));
return csElement;
}
@Override
public ElementCS visitTemplateParameter(@NonNull TemplateParameter object) {
TypeParameterCS csElement = context.refreshElement(TypeParameterCS.class, BaseCSPackage.Literals.TYPE_PARAMETER_CS, object);
csElement.setName(object.getName());
return csElement;
}
@Override
public ElementCS visiting(@NonNull Visitable visitable) {
throw new IllegalArgumentException("Unsupported " + visitable.eClass().getName() + " for AS2CS Declaration pass");
}
}