blob: b9f56d13ac3d62f26a9ea9e1581380f4248ac6b4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012, 2018 Willink Transformations and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* E.D.Willink - initial API and implementation
*******************************************************************************/
package org.eclipse.ocl.xtext.base.attributes;
import java.util.List;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.ocl.pivot.Element;
import org.eclipse.ocl.pivot.NamedElement;
import org.eclipse.ocl.pivot.Namespace;
import org.eclipse.ocl.pivot.internal.scoping.AbstractAttribution;
import org.eclipse.ocl.pivot.internal.scoping.EnvironmentView;
import org.eclipse.ocl.pivot.internal.scoping.ScopeFilter;
import org.eclipse.ocl.pivot.internal.scoping.ScopeView;
import org.eclipse.ocl.xtext.basecs.ImportCS;
import org.eclipse.ocl.xtext.basecs.PathElementCS;
import org.eclipse.ocl.xtext.basecs.PathNameCS;
import org.eclipse.ocl.xtext.basecs.RootCS;
public class PathElementCSAttribution extends AbstractAttribution
{
public static final @NonNull PathElementCSAttribution INSTANCE = new PathElementCSAttribution();
@Override
public ScopeView computeLookup(@NonNull EObject target, @NonNull EnvironmentView environmentView, @NonNull ScopeView scopeView) {
PathElementCS csPathElement = (PathElementCS)target;
EClassifier eClassifier = csPathElement.getElementType();
if (eClassifier == null) { // If this is actually a definition
Element element = csPathElement.basicGetReferredElement();
if (!element.eIsProxy()) {
environmentView.addNamedElement((NamedElement)element);
}
return null;
}
EClassifier savedRequiredType = environmentView.getRequiredType();
boolean savedIsQualifier = environmentView.isQualifier();
ScopeFilter scopeFilter = null;
try {
environmentView.setRequiredType(eClassifier);
PathNameCS csPathName = csPathElement.getOwningPathName();
List<PathElementCS> path = csPathName.getOwnedPathElements();
int index = path.indexOf(csPathElement);
int indexes = path.size();
boolean lastElement = index >= indexes-1;
environmentView.setIsQualifier(!lastElement);
if (lastElement) { // Last element may have a scope filter
scopeFilter = csPathName.getScopeFilter();
if (scopeFilter != null) {
environmentView.addFilter(scopeFilter);
}
}
if ((index == 0) && (1 < indexes)) { // First path element may be an import alias
for (EObject eObject = csPathElement; (eObject = eObject.eContainer()) != null; ) {
if (eObject instanceof ImportCS) {
break;
}
if (eObject instanceof RootCS) {
for (ImportCS csImport : ((RootCS)eObject).getOwnedImports()) {
String aliasName = csImport.getName();
if (aliasName != null) {
Namespace asNamespace = csImport.getReferredNamespace();
if ((asNamespace != null) && !asNamespace.eIsProxy()) {
environmentView.addElement(aliasName, asNamespace);
}
}
}
}
}
if (environmentView.hasFinalResult()) { // If an alias was found
return null;
}
}
if (index <= 0) { // First path element is resolved in parent's parent scope
environmentView.computeLookups(scopeView.getParent().getParent());
}
else { // Subsequent elements in previous scope
Element parent = path.get(index-1).getReferredElement();
if ((parent != null) && !parent.eIsProxy()) {
// environmentView.computeLookups(parent, null);
environmentView.computeQualifiedLookups(parent);
}
}
return null;
}
finally {
if (scopeFilter != null) {
environmentView.removeFilter(scopeFilter);
}
environmentView.setRequiredType(savedRequiredType);
environmentView.setIsQualifier(savedIsQualifier);
}
}
}