001/* 002 * Copyright (c) 2012-2018 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.List; 014import java.util.LinkedList; 015import java.util.Collections; 016 017import gololang.ir.CollectionLiteral.Type; 018 019/** 020 * Represents a collection literal. 021 * 022 * <p>For instance code such as: 023 * <pre class="listing"><code class="lang-golo" data-lang="golo"> 024 * list[1, 2, 3] 025 * </code></pre> 026 * @see Type 027 */ 028public final class CollectionLiteral extends ExpressionStatement<CollectionLiteral> { 029 030 public enum Type { 031 array, list, set, map, tuple, vector, range 032 } 033 034 private final Type type; 035 private final List<ExpressionStatement<?>> expressions = new LinkedList<>(); 036 037 private CollectionLiteral(Type type) { 038 super(); 039 this.type = type; 040 } 041 042 /** 043 * Creates a collection literal of the given type. 044 * 045 * <p>For instance: 046 * <pre class="listing"><code class="lang-java" data-lang="java"> 047 * collection(CollectionLiteral.Type.array, constant(1), constant(2), constant(3)) 048 * </code></pre> 049 * creates 050 * <pre class="listing"><code class="lang-golo" data-lang="golo"> 051 * array[1, 2, 3] 052 * </code></pre> 053 * 054 * @param type the type 055 * @param values expressions to add to the collection 056 */ 057 public static CollectionLiteral create(Object type, Object... values) { 058 CollectionLiteral col = new CollectionLiteral( 059 type instanceof CollectionLiteral.Type 060 ? (CollectionLiteral.Type) type 061 : CollectionLiteral.Type.valueOf(type.toString())); 062 for (Object v : values) { 063 col.add(v); 064 } 065 return col; 066 } 067 068 069 protected CollectionLiteral self() { return this; } 070 071 /** 072 * Adds an expression to the collection. 073 * 074 * @param expression the expression to add. 075 * @return the collection literal. 076 */ 077 public CollectionLiteral add(Object expression) { 078 this.expressions.add(makeParentOf(ExpressionStatement.of(expression))); 079 return this; 080 } 081 082 public Type getType() { 083 return type; 084 } 085 086 public List<ExpressionStatement<?>> getExpressions() { 087 return expressions; 088 } 089 090 @Override 091 public String toString() { 092 return this.type.toString() + this.expressions.toString(); 093 } 094 095 /** 096 * {@inheritDoc} 097 */ 098 @Override 099 public void accept(GoloIrVisitor visitor) { 100 visitor.visitCollectionLiteral(this); 101 } 102 103 /** 104 * {@inheritDoc} 105 */ 106 @Override 107 public List<GoloElement<?>> children() { 108 return Collections.unmodifiableList(expressions); 109 } 110 111 /** 112 * {@inheritDoc} 113 */ 114 @Override 115 protected void replaceElement(GoloElement<?> original, GoloElement<?> newElement) { 116 if (expressions.contains(original) && newElement instanceof ExpressionStatement) { 117 expressions.set(expressions.indexOf(original), ExpressionStatement.of(newElement)); 118 } else { 119 throw cantReplace(original, newElement); 120 } 121 } 122}