/******************************************************************************* * Copyright (c) 2010, 2015 Willink Transformations 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.pivot.internal.scoping; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.ocl.pivot.Element; import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal; import org.eclipse.ocl.pivot.internal.utilities.PivotUtilInternal; /** * ScopeViews support access to some or all of the elements in a scope. * Accesses are filtered on the fly since a cache of results does not remain valid * for long enough to merit it, with incremental reparsing regularly trashing * the CST. */ public class PivotScopeView implements ScopeView { /** * The <code>NULLSCOPEVIEW</code> to be returned by the most outer scope */ public static final @NonNull ScopeView NULLSCOPEVIEW = new ScopeView() { @Override public @NonNull Attribution getAttribution() { return NullAttribution.INSTANCE; } @Override public @Nullable Element getChild() { return null; } @Override public @Nullable EStructuralFeature getContainmentFeature() { return null; } @Override public @NonNull ScopeView getParent() { return NULLSCOPEVIEW; } @Override public @NonNull ScopeView getRoot() { return NULLSCOPEVIEW; } @Override public Element getTarget() { return null; } @Override public boolean isQualified() { return false; } }; protected final @NonNull EnvironmentFactoryInternal environmentFactory; protected final @NonNull Element target; // AST node in which a lookup is to be performed protected final @Nullable Element child; // AST node from which a lookup is to be performed protected final boolean isQualified; // True of the lookup has an explicit namespace qualification private ScopeView parent = null; // Lazily computed scope view for target's parent private Attribution attribution = null; // Lazily computed attributes helper for the target CS node protected PivotScopeView(@NonNull EnvironmentFactoryInternal environmentFactory, @NonNull Element target, @Nullable Element child, boolean isQualified) { this.environmentFactory = environmentFactory; this.target = target; this.child = child; this.isQualified = isQualified; } public @Nullable ScopeView computeLookup(@NonNull EnvironmentView environmentView, @NonNull EObject aTarget) { assert aTarget instanceof Element; if (attribution == null) { attribution = PivotUtilInternal.getAttribution(target); } return attribution.computeLookup(aTarget, environmentView, this); } @Override public @NonNull Attribution getAttribution() { Attribution attribution2 = attribution; if (attribution2 == null) { attribution = attribution2 = PivotUtilInternal.getAttribution(target); } return attribution2; } @Override public @Nullable Element getChild() { return child; } @Override public @Nullable EStructuralFeature getContainmentFeature() { // assert ((child == null) && (containmentFeature == null)) || ((child != null) && (child.eContainmentFeature() == containmentFeature)); return (child != null) ? child.eContainmentFeature() : null; } // public @NonNull MetamodelManager getMetamodelManager() { // return metamodelManager; // } @Override public @NonNull ScopeView getParent() { ScopeView parent2 = parent; if (parent2 == null) { EObject pParent = target.eContainer(); if (pParent instanceof Element) { parent2 = new PivotScopeView(environmentFactory, (Element)pParent, target, isQualified); } else { parent2 = NULLSCOPEVIEW; } parent = parent2; } return parent2; } @Override public @NonNull ScopeView getRoot() { ScopeView parent = getParent(); if (parent == NULLSCOPEVIEW) { return this; } else { return parent.getRoot(); } } @Override public final @NonNull Element getTarget() { return target; } @Override public boolean isQualified() { return isQualified; } @Override public String toString() { Element target = getTarget(); StringBuilder s = new StringBuilder(); s.append("["); //$NON-NLS-1$ s.append(target.eClass().getName()); EStructuralFeature containmentFeature = getContainmentFeature(); if (containmentFeature != null) { s.append("::"); //$NON-NLS-1$ s.append(containmentFeature.getName()); } s.append("] "); //$NON-NLS-1$ s.append(String.valueOf(target)); return s.toString(); } }