/******************************************************************************* * Copyright (c) 2013 itemis AG (http://www.itemis.eu) and others. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. * * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ package org.eclipse.xtext.xbase.typesystem.util; import java.util.Set; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.xtext.common.types.JvmDeclaredType; import org.eclipse.xtext.common.types.JvmMember; import org.eclipse.xtext.common.types.JvmType; import org.eclipse.xtext.common.types.JvmVisibility; import org.eclipse.xtext.common.types.util.RawSuperTypes; import org.eclipse.xtext.util.Strings; import org.eclipse.xtext.xbase.typesystem.references.LightweightTypeReference; /** * @author Sebastian Zarnekow - Initial contribution and API */ public class ContextualVisibilityHelper implements IVisibilityHelper { private JvmType rawContextType; private Set<String> superTypeNames; private IVisibilityHelper parent; private String packageName; public ContextualVisibilityHelper(IVisibilityHelper parent, String packageName) { this.parent = parent; this.packageName = packageName; } public ContextualVisibilityHelper(IVisibilityHelper parent, LightweightTypeReference contextType) { this.parent = parent; this.rawContextType = contextType.getRawTypeReference().getType(); if (rawContextType instanceof JvmDeclaredType) { this.packageName = ((JvmDeclaredType) rawContextType).getPackageName(); } } public ContextualVisibilityHelper(IVisibilityHelper parent, LightweightTypeReference contextType, String packageName) { this.parent = parent; this.rawContextType = contextType.getRawTypeReference().getType(); this.packageName = packageName; } public ContextualVisibilityHelper(IVisibilityHelper parent, JvmType rawContextType, String packageName) { this.parent = parent; this.rawContextType = rawContextType; this.packageName = packageName; } public ContextualVisibilityHelper(IVisibilityHelper parent, JvmType rawContextType) { this.parent = parent; this.rawContextType = rawContextType; if (rawContextType instanceof JvmDeclaredType) { this.packageName = ((JvmDeclaredType) rawContextType).getPackageName(); } } public ContextualVisibilityHelper(LightweightTypeReference contextType) { this(new PublicVisibilityHelper(), contextType); } public JvmType getRawContextType() { return rawContextType; } @Override public boolean isVisible(JvmMember member) { // TODO private visibility? JvmVisibility visibility = member.getVisibility(); if (visibility == JvmVisibility.PUBLIC) { return true; } JvmDeclaredType type = member instanceof JvmDeclaredType ? (JvmDeclaredType) member : member.getDeclaringType(); if (type == rawContextType || EcoreUtil.isAncestor(rawContextType, type)) { return true; } if (type != null && visibility == JvmVisibility.PROTECTED) { if (superTypeNames == null) { this.superTypeNames = computeSuperTypeNames(); } if (superTypeNames.contains(type.getIdentifier())) { return true; } if (type == member) { JvmDeclaredType declaringType = member.getDeclaringType(); if (declaringType != null && superTypeNames.contains(declaringType.getIdentifier())) { return true; } } } if (type != null && (rawContextType == null || rawContextType instanceof JvmDeclaredType) && (visibility == JvmVisibility.DEFAULT || visibility == JvmVisibility.PROTECTED)) { if (Strings.isEmpty(packageName) && Strings.isEmpty(type.getPackageName()) || (packageName != null && packageName.equals(type.getPackageName()))) { return true; } } return parent.isVisible(member); } protected Set<String> computeSuperTypeNames() { return new RawSuperTypes().collectNames(rawContextType); } public String getPackageName() { return packageName; } }