001/* 002 * Copyright (c) 2012-2021 Institut National des Sciences Appliquées de Lyon (INSA Lyon) and others 003 * 004 * This program and the accompanying materials are made available under the 005 * terms of the Eclipse Public License 2.0 which is available at 006 * http://www.eclipse.org/legal/epl-2.0. 007 * 008 * SPDX-License-Identifier: EPL-2.0 009 */ 010 011package gololang.ir; 012 013import java.util.*; 014import org.eclipse.golo.compiler.PackageAndClass; 015import static gololang.Messages.message; 016 017/** 018 * Named augmentation definition. 019 */ 020public final class NamedAugmentation extends GoloElement<NamedAugmentation> implements FunctionContainer, ToplevelGoloElement, NamedElement { 021 private final PackageAndClass name; 022 private final Set<GoloFunction> functions = new LinkedHashSet<>(); 023 private final Set<MacroInvocation> macroCalls = new LinkedHashSet<>(); 024 025 private NamedAugmentation(PackageAndClass name) { 026 super(); 027 this.name = name; 028 } 029 030 /** 031 * Creates a named augmentation. 032 * 033 * @param name the name of the augmentation (compatible with {@link PackageAndClass#of(Object)}) 034 */ 035 public static NamedAugmentation of(Object name) { 036 return new NamedAugmentation(PackageAndClass.of(name)); 037 } 038 039 @Override 040 public String getName() { 041 return this.name.toString(); 042 } 043 044 public PackageAndClass getPackageAndClass() { 045 return this.name; 046 } 047 048 protected NamedAugmentation self() { return this; } 049 050 /** 051 * {@inheritDoc} 052 */ 053 @Override 054 public List<GoloFunction> getFunctions() { 055 return new ArrayList<>(functions); 056 } 057 058 /** 059 * {@inheritDoc} 060 */ 061 @Override 062 public void addFunction(GoloFunction func) { 063 if (func.getArity() == 0) { 064 throw new IllegalArgumentException(message("augment_function_no_args", func.getName(), this.getPackageAndClass())); 065 } 066 functions.add(makeParentOf(func)); 067 } 068 069 /** 070 * {@inheritDoc} 071 */ 072 @Override 073 public void addMacroInvocation(MacroInvocation macroCall) { 074 macroCalls.add(macroCall); 075 makeParentOf(macroCall); 076 } 077 078 /** 079 * {@inheritDoc} 080 */ 081 @Override 082 public boolean hasFunctions() { 083 return !functions.isEmpty(); 084 } 085 086 /** 087 * Adds the elements to this augmentation. 088 * 089 * <p>This is a builder method. 090 * 091 * @see FunctionContainer#addElement(Object) 092 */ 093 public NamedAugmentation add(Object... elts) { 094 for (Object elt : elts) { 095 addElement(elt); 096 } 097 return this; 098 } 099 100 /** 101 * {@inheritDoc} 102 */ 103 @Override 104 public void accept(GoloIrVisitor visitor) { 105 visitor.visitNamedAugmentation(this); 106 } 107 108 /** 109 * {@inheritDoc} 110 */ 111 @Override 112 public List<GoloElement<?>> children() { 113 LinkedList<GoloElement<?>> children = new LinkedList<>(functions); 114 children.addAll(macroCalls); 115 return children; 116 } 117 118 /** 119 * {@inheritDoc} 120 */ 121 @Override 122 protected void replaceElement(GoloElement<?> original, GoloElement<?> newElement) { 123 if (functions.contains(original)) { 124 functions.remove(original); 125 } else if (macroCalls.contains(original)) { 126 macroCalls.remove(original); 127 } else { 128 throw cantReplace(original, newElement); 129 } 130 addElement(newElement); 131 } 132}