/** * Copyright 2015 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ package com.jogamp.gluegen.cgram.types; import java.util.HashSet; import java.util.Set; /** * Supports symbol aliasing, i.e. renaming, * while preserving all its original names, i.e. aliases. */ public interface AliasedSymbol { /** * Rename this symbol with the given {@code newName} if not equal {@link #getName() current-name}. * <p> * Before renaming the {@link #getName() current-name} will be added * to the list of {@link #getAliasedNames() aliases}. * while the given {@code newName} will be removed. * </p> * <p> * Operation will be ignored if {@code newName} is {@code null}. * </p> * @param newName the new {@link #getName() current-name}, maybe {@code null} */ void rename(final String newName); /** * Add the given {@code origName} to the list of {@link #getAliasedNames() aliases} * if not equal {@link #getName() current-name}. * <p> * Operation will be ignored if {@code newName} is {@code null}. * </p> * @param origName the new alias to be added, maybe {@code null} */ void addAliasedName(final String origName); /** * * Returns {@code true} if this symbol has aliases, i.e. either being {@link #rename(String) renamed} * or {@link #addAliasedName(String) aliases-added}. * <p> * Otherwise {@code false} is being returned. * </p> */ boolean hasAliases(); /** * Return all aliases for this symbol, i.e. original names, for this symbol. * <p> * Inclusive {@link #getOrigName() original-name}, if {@link #rename(String) renamed}, * </p> * <p> * Exclusive {@link #getName() current-name}. * </p> * <p> * May return {@code null} or a zero sized {@link Set} for no aliases. * </p> */ Set<String> getAliasedNames(); /** * Return the original-name as set at creation. */ String getOrigName(); /** * Return the current-name, which is the last {@link #rename(String) renamed-name} if issued, * or the {@link #getOrigName() original-name}. */ String getName(); /** * Return this object's {@link #toString()} wrapped w/ the {@link #getName() current-name} * and all {@link #getAliasedNames() aliases}. */ String getAliasedString(); public static class AliasedSymbolImpl implements AliasedSymbol { private final String origName; private final HashSet<String> aliasedNames; private String name; public AliasedSymbolImpl(final String origName) { if( null == origName ) { throw new IllegalArgumentException("Null origName not allowed"); } this.origName = origName; this.aliasedNames=new HashSet<String>(); this.name = origName; } public AliasedSymbolImpl(final AliasedSymbolImpl o) { this.origName = o.origName; this.aliasedNames = new HashSet<String>(o.aliasedNames); this.name = o.name; } @Override public void rename(final String newName) { if( null != newName && !name.equals(newName) ) { aliasedNames.add(name); aliasedNames.remove(newName); name = newName; } } @Override public void addAliasedName(final String origName) { if( null != origName && !name.equals(origName) ) { aliasedNames.add(origName); } } @Override public boolean hasAliases() { return aliasedNames.size() > 0; } @Override public Set<String> getAliasedNames() { return aliasedNames; } @Override public String getOrigName() { return origName; } @Override public String getName() { return name; } @Override public String getAliasedString() { return "["+name+", aliases "+aliasedNames.toString()+", "+toString()+"]"; } } public static class NoneAliasedSymbol implements AliasedSymbol { private final String name; public NoneAliasedSymbol(final String origName) { this.name = origName; } @Override public void rename(final String newName) { throw new UnsupportedOperationException(); } @Override public void addAliasedName(final String origName) { throw new UnsupportedOperationException(); } @Override public boolean hasAliases() { return false; } @Override public Set<String> getAliasedNames() { return null; } @Override public String getOrigName() { return name; } @Override public String getName() { return name; } @Override public String getAliasedString() { return toString(); } } }