1 /* 2 * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 * 25 */ 26 27 package jdk.internal.jextract.impl; 28 29 import java.lang.constant.Constable; 30 import java.util.Collections; 31 import java.util.HashMap; 32 import java.util.List; 33 import java.util.Map; 34 import java.util.Objects; 35 import java.util.Optional; 36 import java.util.Set; 37 import jdk.incubator.foreign.MemoryLayout; 38 import jdk.incubator.jextract.Declaration; 39 import jdk.incubator.jextract.Position; 40 import jdk.incubator.jextract.Type; 41 42 public abstract class DeclarationImpl implements Declaration { 43 44 private final String name; 45 private final Position pos; 46 private final Optional<Map<String, List<Constable>>> attributes; 47 48 public DeclarationImpl(String name, Position pos, Map<String, List<Constable>> attrs) { 49 this.name = name; 50 this.pos = pos; 51 this.attributes = Optional.ofNullable(attrs); 52 } 53 54 public String toString() { 55 return new PrettyPrinter().print(this); 56 } 57 58 public String name() { 59 return name; 60 } 61 62 @Override 63 public Position pos() { 64 return pos; 65 } 66 67 @Override 68 public Optional<List<Constable>> getAttribute(String name) { 69 return attributes.map(attrs -> attrs.get(name)); 70 } 71 72 @Override 73 public Set<String> attributeNames() { return Collections.unmodifiableSet( 74 attributes.map(Map::keySet).orElse(Collections.emptySet())); 75 } 76 77 @Override 78 public Declaration withAttribute(String name, Constable... values) { 79 if (values == null || values.length == 0) { 80 return withAttributes(null); 81 } 82 var attrs = attributes.map(HashMap::new).orElseGet(HashMap::new); 83 attrs.put(name, List.of(values)); 84 return withAttributes(attrs); 85 } 86 87 abstract protected Declaration withAttributes(Map<String, List<Constable>> attrs); 88 89 @Override 90 public boolean equals(Object o) { 91 if (this == o) return true; 92 if (!(o instanceof Declaration)) return false; 93 Declaration decl = (Declaration) o; 94 return name().equals(decl.name()); 95 } 96 97 @Override 98 public int hashCode() { 99 return Objects.hash(name); 100 } 101 102 public static final class TypedefImpl extends DeclarationImpl implements Declaration.Typedef { 103 final Type type; 104 105 public TypedefImpl(Type type, String name, Position pos, Map<String, List<Constable>> attrs) { 106 super(name, pos, attrs); 107 this.type = Objects.requireNonNull(type); 108 } 109 110 @Override 111 public <R, D> R accept(Visitor<R, D> visitor, D data) { 112 return visitor.visitTypedef(this, data); 113 } 114 115 @Override 116 public Type type() { 117 return type; 118 } 119 120 @Override 121 public Typedef withAttributes(Map<String, List<Constable>> attrs) { 122 return new TypedefImpl(type, name(), pos(), attrs); 123 } 124 125 @Override 126 public Typedef stripAttributes() { 127 return new TypedefImpl(type, name(), pos(), null); 128 } 129 130 @Override 131 public boolean equals(Object o) { 132 if (this == o) return true; 133 if (!(o instanceof Declaration.Typedef)) return false; 134 135 Declaration.Typedef other = (Declaration.Typedef) o; 136 return name().equals(other.name()) && 137 type.equals(other.type()); 138 } 139 140 @Override 141 public int hashCode() { 142 return Objects.hash(super.hashCode(), type); 143 } 144 } 145 146 public static final class VariableImpl extends DeclarationImpl implements Declaration.Variable { 147 148 final Variable.Kind kind; 149 final Type type; 150 final Optional<MemoryLayout> layout; 151 152 private VariableImpl(Type type, Optional<MemoryLayout> layout, Variable.Kind kind, String name, Position pos, Map<String, List<Constable>> attrs) { 153 super(name, pos, attrs); 154 this.kind = Objects.requireNonNull(kind); 155 this.type = Objects.requireNonNull(type); 156 this.layout = Objects.requireNonNull(layout); 157 } 158 159 public VariableImpl(Type type, Variable.Kind kind, String name, Position pos) { 160 this(type, TypeImpl.getLayout(type), kind, name, pos, null); 161 } 162 163 public VariableImpl(Type type, MemoryLayout layout, Variable.Kind kind, String name, Position pos) { 164 this(type, Optional.of(layout), kind, name, pos, null); 165 } 166 167 @Override 168 public Kind kind() { 169 return kind; 170 } 171 172 @Override 173 public <R, D> R accept(Visitor<R, D> visitor, D data) { 174 return visitor.visitVariable(this, data); 175 } 176 177 @Override 178 public Type type() { 179 return type; 180 } 181 182 @Override 183 public Optional<MemoryLayout> layout() { 184 return layout; 185 } 186 187 @Override 188 public Variable withAttributes(Map<String, List<Constable>> attrs) { 189 return new VariableImpl(type, layout, kind, name(), pos(), attrs); 190 } 191 192 @Override 193 public Variable stripAttributes() { 194 return new VariableImpl(type, layout, kind, name(), pos(), null); 195 } 196 197 @Override 198 public boolean equals(Object o) { 199 if (this == o) return true; 200 if (!(o instanceof Declaration.Variable)) return false; 201 202 Declaration.Variable variable = (Declaration.Variable) o; 203 if (!super.equals(o)) return false; 204 return kind == variable.kind() && 205 type.equals(variable.type()); 206 } 207 208 @Override 209 public int hashCode() { 210 return Objects.hash(super.hashCode(), kind, type); 211 } 212 } 213 214 public static final class FunctionImpl extends DeclarationImpl implements Declaration.Function { 215 216 final List<Variable> params; 217 final Type.Function type; 218 219 public FunctionImpl(Type.Function type, List<Variable> params, String name, Position pos) { 220 this(type, params, name, pos, null); 221 } 222 223 public FunctionImpl(Type.Function type, List<Variable> params, String name, Position pos, Map<String, List<Constable>> attrs) { 224 super(name, pos, attrs); 225 this.params = Objects.requireNonNull(params); 226 this.type = Objects.requireNonNull(type); 227 } 228 229 @Override 230 public <R, D> R accept(Visitor<R, D> visitor, D data) { 231 return visitor.visitFunction(this, data); 232 } 233 234 @Override 235 public List<Variable> parameters() { 236 return params; 237 } 238 239 @Override 240 public Type.Function type() { 241 return type; 242 } 243 244 @Override 245 public Function withAttributes(Map<String, List<Constable>> attrs) { 246 return new FunctionImpl(type, params, name(), pos(), attrs); 247 } 248 249 @Override 250 public Function stripAttributes() { 251 return new FunctionImpl(type, params, name(), pos(), null); 252 } 253 254 @Override 255 public boolean equals(Object o) { 256 if (this == o) return true; 257 if (!(o instanceof Declaration.Function)) return false; 258 if (!super.equals(o)) return false; 259 260 Declaration.Function function = (Declaration.Function) o; 261 return type.equals(function.type()); 262 } 263 264 @Override 265 public int hashCode() { 266 return Objects.hash(super.hashCode(), type); 267 } 268 } 269 270 public static class ScopedImpl extends DeclarationImpl implements Declaration.Scoped { 271 272 private final Scoped.Kind kind; 273 private final List<Declaration> declarations; 274 private final Optional<MemoryLayout> optLayout; 275 276 public ScopedImpl(Kind kind, MemoryLayout layout, List<Declaration> declarations, String name, Position pos) { 277 this(kind, Optional.of(layout), declarations, name, pos, null); 278 } 279 280 public ScopedImpl(Kind kind, List<Declaration> declarations, String name, Position pos) { 281 this(kind, Optional.empty(), declarations, name, pos, null); 282 } 283 284 ScopedImpl(Kind kind, Optional<MemoryLayout> optLayout, List<Declaration> declarations, 285 String name, Position pos, Map<String, List<Constable>> attrs) { 286 super(name, pos, attrs); 287 this.kind = Objects.requireNonNull(kind); 288 this.declarations = Objects.requireNonNull(declarations); 289 this.optLayout = Objects.requireNonNull(optLayout); 290 } 291 292 @Override 293 public <R, D> R accept(Visitor<R, D> visitor, D data) { 294 return visitor.visitScoped(this, data); 295 } 296 297 @Override 298 public List<Declaration> members() { 299 return declarations; 300 } 301 302 @Override 303 public Optional<MemoryLayout> layout() { 304 return optLayout; 305 } 306 307 @Override 308 public Kind kind() { 309 return kind; 310 } 311 312 @Override 313 public Scoped withAttributes(Map<String, List<Constable>> attrs) { 314 return new ScopedImpl(kind, optLayout, declarations, name(), pos(), attrs); 315 } 316 317 @Override 318 public Scoped stripAttributes() { 319 return new ScopedImpl(kind, optLayout, declarations, name(), pos(), null); 320 } 321 322 @Override 323 public boolean equals(Object o) { 324 if (this == o) return true; 325 if (!(o instanceof Declaration.Scoped)) return false; 326 if (!super.equals(o)) return false; 327 Declaration.Scoped scoped = (Declaration.Scoped) o; 328 return kind == scoped.kind() && 329 declarations.equals(scoped.members()); 330 } 331 332 @Override 333 public int hashCode() { 334 return Objects.hash(super.hashCode(), kind, declarations); 335 } 336 } 337 338 public static final class ConstantImpl extends DeclarationImpl implements Declaration.Constant { 339 340 final Object value; 341 final Type type; 342 343 public ConstantImpl(Type type, Object value, String name, Position pos) { 344 this(type, value, name, pos, null); 345 } 346 347 public ConstantImpl(Type type, Object value, String name, Position pos, Map<String, List<Constable>> attrs) { 348 super(name, pos, attrs); 349 this.value = Objects.requireNonNull(value); 350 this.type = Objects.requireNonNull(type); 351 } 352 353 @Override 354 public <R, D> R accept(Visitor<R, D> visitor, D data) { 355 return visitor.visitConstant(this, data); 356 } 357 358 @Override 359 public Object value() { 360 return value; 361 } 362 363 @Override 364 public Type type() { 365 return type; 366 } 367 368 @Override 369 public Constant withAttributes(Map<String, List<Constable>> attrs) { 370 return new ConstantImpl(type, value, name(), pos(), attrs); 371 } 372 373 @Override 374 public Constant stripAttributes() { 375 return new ConstantImpl(type, value, name(), pos(), null); 376 } 377 378 @Override 379 public boolean equals(Object o) { 380 if (this == o) return true; 381 if (!(o instanceof Declaration.Constant)) return false; 382 if (!super.equals(o)) return false; 383 Declaration.Constant constant = (Declaration.Constant) o; 384 return value.equals(constant.value()) && 385 type.equals(constant.type()); 386 } 387 388 @Override 389 public int hashCode() { 390 return Objects.hash(super.hashCode(), value, type); 391 } 392 } 393 }