All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jnario.feature.jvmmodel.JvmFieldReferenceUpdater Maven / Gradle / Ivy

The newest version!
package org.jnario.feature.jvmmodel;

import static com.google.common.base.Objects.equal;
import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Iterables.filter;
import org.eclipse.emf.ecore.util.EcoreUtil;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.common.types.JvmField;
import org.eclipse.xtext.common.types.JvmGenericType;
import org.eclipse.xtext.common.types.JvmMember;
import org.eclipse.xtext.common.types.JvmType;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.xbase.jvmmodel.IJvmModelAssociations;
import org.eclipse.xtext.xbase.util.XbaseUsageCrossReferencer;
import org.jnario.jvmmodel.ExtendedJvmTypesBuilder;

import com.google.inject.Inject;

public class JvmFieldReferenceUpdater {
	
	@SuppressWarnings("serial")
	private class FieldReferenceFinder extends XbaseUsageCrossReferencer{

		private JvmGenericType newType;
		private JvmGenericType originalType;

		protected FieldReferenceFinder(EObject eObject) {
			super(eObject);
		}
		
		protected boolean crossReference(EObject eObject, EReference eReference, EObject crossReferencedEObject) {
			if(crossReferencedEObject instanceof JvmField){
				return updateFieldReference(eObject, eReference, (JvmField)crossReferencedEObject);
			}
			if(crossReferencedEObject == originalType){
				EcoreUtil.replace(eObject, eReference, originalType, newType);
			}
			return false;
		}

		protected boolean updateFieldReference(EObject eObject,
				EReference eReference, JvmField sourceField) {
			if(sourceField.isStatic()){
				return false;
			}
			if(!sourceField.getDeclaringType().getSimpleName().equals(originalType.getSimpleName())){
				return false;
			}
			JvmField newField = findMatchingField(sourceField);
			EcoreUtil.replace(eObject, eReference, sourceField, newField);
			return true;
		}
		
		private JvmField findMatchingField(JvmField sourceField) {
			Iterable members = allMembersOf(newType);
			for (JvmField candidate : filter(members, JvmField.class)) {
				if(candidate.getSimpleName() == null && equal(candidate.getType().getQualifiedName(), sourceField.getType().getQualifiedName())){
					candidate.setSimpleName(sourceField.getSimpleName());
					return candidate;
				}
				if(equal(candidate.getSimpleName(), sourceField.getSimpleName())){
					return candidate;
				}
			}
			EObject source = associations.getPrimarySourceElement(sourceField);
			JvmField newField = typesBuilder.toField(source, sourceField.getSimpleName(), sourceField.getType());
			newType.getMembers().add(newField);
			return newField;
		}

		public Iterable allMembersOf(JvmGenericType type) {
			Iterable members = type.getMembers();
			for (JvmTypeReference superTypeReference : type.getSuperTypes()) {
				JvmType superType = superTypeReference.getType();
				if(superType != null && superType instanceof JvmGenericType){
					members = concat(members, ((JvmGenericType)superType).getMembers());
				}
			}
			return members;
		}

		public void updateFields(JvmGenericType originalType, JvmGenericType newType){
			this.originalType = originalType;
			this.newType = newType;
			crossReference();
			done();
		}
		
		@Override
		protected void done() {
			super.done();
			newType = null;
		}
	}
	
	@Inject ExtendedJvmTypesBuilder typesBuilder;
	@Inject IJvmModelAssociations associations;
	
	public void updateReferences(EObject eObject, JvmGenericType originalType, JvmGenericType newType) {
		FieldReferenceFinder referenceFinder = new FieldReferenceFinder(eObject);
		referenceFinder.updateFields(originalType, newType);
	}
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy