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.incubator.jextract; 28 29 import java.lang.constant.Constable; 30 import java.util.List; 31 import java.util.Optional; 32 import java.util.Set; 33 import java.util.stream.Collectors; 34 import java.util.stream.Stream; 35 import jdk.incubator.foreign.MemoryLayout; 36 import jdk.internal.jextract.impl.DeclarationImpl; 37 38 /** 39 * Instances of this class are used to model declaration elements in the foreign language. 40 * All declarations have a position (see {@link Position}) and a name. Instances of this class 41 * support the <em>visitor</em> pattern (see {@link Declaration#accept(Visitor, Object)} and 42 * {@link Visitor}). 43 */ 44 public interface Declaration { 45 46 /** 47 * The position associated with this declaration. 48 * @return The position associated with this declaration. 49 */ 50 Position pos(); 51 52 /** 53 * The name associated with this declaration. 54 * @return The name associated with this declaration. 55 */ 56 String name(); 57 58 /** 59 * Get a declaration with specified attribute. 60 * Set the values to the specified attribute while other attributes remains unchanged. If the specified attribute 61 * already exist, the new values are replacing the old ones. By not specifying any value, the attribute will become 62 * empty as {@link #getAttribute(String) getAttribute(name).isEmpty()} will return true. 63 * @param name The attribute name 64 * @param values More attribute values 65 * @return the Declaration with attributes 66 */ 67 Declaration withAttribute(String name, Constable... values); 68 69 /** 70 * Get a declaration without current attributes 71 * @return the Declatation without any attributes 72 */ 73 Declaration stripAttributes(); 74 75 /** 76 * The values of the specified attribute. 77 * @param name The attribute to retrieve 78 * @return The list of values associate with this attribute 79 */ 80 Optional<List<Constable>> getAttribute(String name); 81 82 /** 83 * The attributes associated with this declaration 84 * @return The attributes associated with this declaration 85 */ 86 Set<String> attributeNames(); 87 88 /** 89 * Entry point for visiting declaration instances. 90 * @param visitor the declaration visitor. 91 * @param data optional data to be passed to the visitor. 92 * @param <R> the visitor's return type. 93 * @param <D> the visitor's argument type. 94 * @return the result of visiting this declaration through the specified declaration visitor. 95 */ 96 <R,D> R accept(Visitor<R, D> visitor, D data); 97 98 /** 99 * Compares the specified object with this Declaration for equality. Returns 100 * {@code true} if and only if the specified object is also a Declaration and both 101 * the declarations are <i>equal</i>. 102 * 103 * @param o the object to be compared for equality with this Declaration 104 * @return {@code true} if the specified object is equal to this Declaration 105 */ 106 boolean equals(Object o); 107 108 /** 109 * Returns the hash code value for this Declaration. 110 * 111 * @return the hash code value for this Declaration. 112 */ 113 int hashCode(); 114 115 /** 116 * A function declaration. 117 */ 118 interface Function extends Declaration { 119 /** 120 * The parameters associated with this function declaration. 121 * @return The parameters associated with this function declaration. 122 */ 123 List<Variable> parameters(); 124 125 /** 126 * The foreign type associated with this function declaration. 127 * @return The foreign type associated with this function declaration. 128 */ 129 Type.Function type(); 130 } 131 132 /** 133 * A scoped declaration is a container for one or more nested declarations. This declaration can be used to model 134 * several constructs in the foreign languages, such as (but not limited to) structs, unions and structs (see also 135 * {@link Scoped.Kind}). 136 */ 137 interface Scoped extends Declaration { 138 139 /** 140 * The scoped declaration kind. 141 */ 142 enum Kind { 143 /** 144 * Namespace declaration. 145 */ 146 NAMESPACE, 147 /** 148 * Class declaration. 149 */ 150 CLASS, 151 /** 152 * Enum declaration. 153 */ 154 ENUM, 155 /** 156 * Struct declaration. 157 */ 158 STRUCT, 159 /** 160 * Union declaration. 161 */ 162 UNION, 163 /** 164 * Bitfields declaration. 165 */ 166 BITFIELDS, 167 /** 168 * Toplevel declaration. 169 */ 170 TOPLEVEL; 171 } 172 173 /** 174 * The member declarations associated with this scoped declaration. 175 * @return The member declarations associated with this scoped declaration. 176 */ 177 List<Declaration> members(); 178 179 /** 180 * The (optional) layout associated with this scoped declaration. 181 * @return The (optional) layout associated with this scoped declaration. 182 * 183 * @implSpec a layout is present if the scoped declaration kind is one of {@link Kind#STRUCT}, {@link Kind#UNION}, 184 * {@link Kind#ENUM}, {@link Kind#BITFIELDS}, {@link Kind#CLASS} <em>and</em> if this declaration models an entity in the foreign 185 * language that is associated with a <em>definition</em>. 186 */ 187 Optional<MemoryLayout> layout(); 188 189 /** 190 * The scoped declaration kind. 191 * @return The scoped declaration kind. 192 */ 193 Kind kind(); 194 } 195 196 /** 197 * A typedef declaration 198 */ 199 interface Typedef extends Declaration { 200 /** 201 * The canonical type associated with this typedef declaration. 202 * @return The canonical type associated with this typedef declaration. 203 */ 204 Type type(); 205 } 206 207 /** 208 * A variable declaration. 209 */ 210 interface Variable extends Declaration { 211 /** 212 * The variable declaration kind. 213 */ 214 enum Kind { 215 /** 216 * Global variable declaration. 217 */ 218 GLOBAL, 219 /** 220 * Field declaration. 221 */ 222 FIELD, 223 /** 224 * Bitfield declaration. 225 */ 226 BITFIELD, 227 /** 228 * Function parameter declaration. 229 */ 230 PARAMETER; 231 } 232 233 /** 234 * The type associated with this variable declaration. 235 * @return The type associated with this variable declaration. 236 */ 237 Type type(); 238 239 /** 240 * The optional layout associated with this variable declaration. 241 * @return The optional layout associated with this variable declaration. 242 */ 243 Optional<MemoryLayout> layout(); 244 245 /** 246 * The kind associated with this variable declaration. 247 * @return The kind associated with this variable declaration. 248 */ 249 Kind kind(); 250 } 251 252 /** 253 * A constant value declaration. 254 */ 255 interface Constant extends Declaration { 256 /** 257 * The value associated with this constant declaration. 258 * @return The value associated with this constant declaration. 259 */ 260 Object value(); 261 262 /** 263 * The type associated with this constant declaration. 264 * @return The type associated with this constant declaration. 265 */ 266 Type type(); 267 } 268 269 /** 270 * Declaration visitor interface. 271 * @param <R> the visitor's return type. 272 * @param <P> the visitor's parameter type. 273 */ 274 interface Visitor<R,P> { 275 /** 276 * Visit a scoped declaration. 277 * @param d the scoped declaration. 278 * @param p the visitor parameter. 279 * @return the result of visiting the given scoped declaration through this visitor object. 280 */ 281 default R visitScoped(Scoped d, P p) { return visitDeclaration(d, p); } 282 283 /** 284 * Visit a function declaration. 285 * @param d the function declaration. 286 * @param p the visitor parameter. 287 * @return the result of visiting the given function declaration through this visitor object. 288 */ 289 default R visitFunction(Function d, P p) { return visitDeclaration(d, p); } 290 291 /** 292 * Visit a variable declaration. 293 * @param d the variable declaration. 294 * @param p the visitor parameter. 295 * @return the result of visiting the given variable declaration through this visitor object. 296 */ 297 default R visitVariable(Variable d, P p) { return visitDeclaration(d, p); } 298 299 /** 300 * Visit a constant declaration. 301 * @param d the constant declaration. 302 * @param p the visitor parameter. 303 * @return the result of visiting the given constant declaration through this visitor object. 304 */ 305 default R visitConstant(Constant d, P p) { return visitDeclaration(d, p); } 306 307 /** 308 * Visit a typedef declaration. 309 * @param d the typedef declaration. 310 * @param p the visitor parameter. 311 * @return the result of visiting the given typedef declaration through this visitor object. 312 */ 313 default R visitTypedef(Typedef d, P p) { return visitDeclaration(d, p); } 314 315 /** 316 * Visit a declaration. 317 * @param d the declaration. 318 * @param p the visitor parameter. 319 * @return the result of visiting the given declaration through this visitor object. 320 */ 321 default R visitDeclaration(Declaration d, P p) { throw new UnsupportedOperationException(); } 322 } 323 324 /** 325 * Creates a new constant declaration with given name and type. 326 * @param pos the constant declaration position. 327 * @param name the constant declaration name. 328 * @param value the constant declaration value. 329 * @param type the constant declaration type. 330 * @return a new constant declaration with given name and type. 331 */ 332 static Declaration.Constant constant(Position pos, String name, Object value, Type type) { 333 return new DeclarationImpl.ConstantImpl(type, value, name, pos); 334 } 335 336 /** 337 * Creates a new global variable declaration with given name and type. 338 * @param pos the global variable declaration position. 339 * @param name the global variable declaration name. 340 * @param type the global variable declaration type. 341 * @return a new global variable declaration with given name and type. 342 */ 343 static Declaration.Variable globalVariable(Position pos, String name, Type type) { 344 return new DeclarationImpl.VariableImpl(type, Declaration.Variable.Kind.GLOBAL, name, pos); 345 } 346 347 /** 348 * Creates a new field declaration with given name and type. 349 * @param pos the field declaration position. 350 * @param name the field declaration name. 351 * @param type the field declaration type. 352 * @return a new field declaration with given name and type. 353 */ 354 static Declaration.Variable field(Position pos, String name, Type type) { 355 return new DeclarationImpl.VariableImpl(type, Declaration.Variable.Kind.FIELD, name, pos); 356 } 357 358 /** 359 * Creates a new bitfield declaration with given name, type and layout. 360 * @param pos the bitfield declaration position. 361 * @param name the bitfield declaration name. 362 * @param type the bitfield declaration type. 363 * @param layout the bitfield declaration layout. 364 * @return a new bitfield declaration with given name, type and layout. 365 */ 366 static Declaration.Variable bitfield(Position pos, String name, Type type, MemoryLayout layout) { 367 return new DeclarationImpl.VariableImpl(type, layout, Declaration.Variable.Kind.BITFIELD, name, pos); 368 } 369 370 /** 371 * Creates a new parameter declaration with given name and type. 372 * @param pos the parameter declaration position. 373 * @param name the parameter declaration name. 374 * @param type the parameter declaration type. 375 * @return a new parameter declaration with given name and type. 376 */ 377 static Declaration.Variable parameter(Position pos, String name, Type type) { 378 return new DeclarationImpl.VariableImpl(type, Declaration.Variable.Kind.PARAMETER, name, pos); 379 } 380 381 /** 382 * Creates a new toplevel declaration with given member declarations. 383 * @param pos the toplevel declaration position. 384 * @param decls the toplevel declaration member declarations. 385 * @return a new toplevel declaration with given member declarations. 386 */ 387 static Declaration.Scoped toplevel(Position pos, Declaration... decls) { 388 List<Declaration> declList = Stream.of(decls).collect(Collectors.toList()); 389 return new DeclarationImpl.ScopedImpl(Declaration.Scoped.Kind.TOPLEVEL, declList, "<toplevel>", pos); 390 } 391 392 /** 393 * Creates a new namespace declaration with given name and member declarations. 394 * @param pos the namespace declaration position. 395 * @param name the namespace declaration name. 396 * @param decls the namespace declaration member declarations. 397 * @return a new namespace declaration with given name and member declarations. 398 */ 399 static Declaration.Scoped namespace(Position pos, String name, Declaration... decls) { 400 List<Declaration> declList = Stream.of(decls).collect(Collectors.toList()); 401 return new DeclarationImpl.ScopedImpl(Declaration.Scoped.Kind.NAMESPACE, declList, name, pos); 402 } 403 404 /** 405 * Creates a new bitfields group declaration with given name and layout. 406 * @param pos the bitfields group declaration position. 407 * @param layout the bitfields group declaration layout. 408 * @param bitfields the bitfields group member declarations. 409 * @return a new bitfields group declaration with given name and layout. 410 */ 411 static Declaration.Scoped bitfields(Position pos, MemoryLayout layout, Declaration.Variable... bitfields) { 412 List<Declaration> declList = Stream.of(bitfields).collect(Collectors.toList()); 413 return new DeclarationImpl.ScopedImpl(Declaration.Scoped.Kind.BITFIELDS, layout, declList, "", pos); 414 } 415 416 /** 417 * Creates a new struct declaration with given name and member declarations. 418 * @param pos the struct declaration position. 419 * @param name the struct declaration name. 420 * @param decls the struct declaration member declarations. 421 * @return a new struct declaration with given name, layout and member declarations. 422 */ 423 static Declaration.Scoped struct(Position pos, String name, Declaration... decls) { 424 List<Declaration> declList = Stream.of(decls).collect(Collectors.toList()); 425 return new DeclarationImpl.ScopedImpl(Declaration.Scoped.Kind.STRUCT, declList, name, pos); 426 } 427 428 /** 429 * Creates a new struct declaration with given name, layout and member declarations. 430 * @param pos the struct declaration position. 431 * @param name the struct declaration name. 432 * @param layout the struct declaration layout. 433 * @param decls the struct declaration member declarations. 434 * @return a new struct declaration with given name, layout and member declarations. 435 */ 436 static Declaration.Scoped struct(Position pos, String name, MemoryLayout layout, Declaration... decls) { 437 List<Declaration> declList = Stream.of(decls).collect(Collectors.toList()); 438 return new DeclarationImpl.ScopedImpl(Declaration.Scoped.Kind.STRUCT, layout, declList, name, pos); 439 } 440 441 /** 442 * Creates a new union declaration with given name and member declarations. 443 * @param pos the union declaration position. 444 * @param name the union declaration name. 445 * @param decls the union declaration member declarations. 446 * @return a new union declaration with given name and member declarations. 447 */ 448 static Declaration.Scoped union(Position pos, String name, Declaration... decls) { 449 List<Declaration> declList = Stream.of(decls).collect(Collectors.toList()); 450 return new DeclarationImpl.ScopedImpl(Scoped.Kind.UNION, declList, name, pos); 451 } 452 453 /** 454 * Creates a new union declaration with given name, layout and member declarations. 455 * @param pos the union declaration position. 456 * @param name the union declaration name. 457 * @param layout the union declaration layout. 458 * @param decls the union declaration member declarations. 459 * @return a new union declaration with given name, layout and member declarations. 460 */ 461 static Declaration.Scoped union(Position pos, String name, MemoryLayout layout, Declaration... decls) { 462 List<Declaration> declList = Stream.of(decls).collect(Collectors.toList()); 463 return new DeclarationImpl.ScopedImpl(Declaration.Scoped.Kind.UNION, layout, declList, name, pos); 464 } 465 466 /** 467 * Creates a new class declaration with given name and member declarations. 468 * @param pos the class declaration position. 469 * @param name the class declaration name. 470 * @param decls the class declaration member declarations. 471 * @return a new class declaration with given name and member declarations. 472 */ 473 static Declaration.Scoped class_(Position pos, String name, Declaration... decls) { 474 List<Declaration> declList = Stream.of(decls).collect(Collectors.toList()); 475 return new DeclarationImpl.ScopedImpl(Declaration.Scoped.Kind.CLASS, declList, name, pos); 476 } 477 478 /** 479 * Creates a new class declaration with given name, layout and member declarations. 480 * @param pos the class declaration position. 481 * @param name the class declaration name. 482 * @param layout the class declaration layout. 483 * @param decls the class declaration member declarations. 484 * @return a new class declaration with given name, layout and member declarations. 485 */ 486 static Declaration.Scoped class_(Position pos, String name, MemoryLayout layout, Declaration... decls) { 487 List<Declaration> declList = Stream.of(decls).collect(Collectors.toList()); 488 return new DeclarationImpl.ScopedImpl(Declaration.Scoped.Kind.CLASS, layout, declList, name, pos); 489 } 490 491 /** 492 * Creates a new enum declaration with given name and member declarations. 493 * @param pos the enum declaration position. 494 * @param name the enum declaration name. 495 * @param decls the enum declaration member declarations. 496 * @return a new enum declaration with given name, layout and member declarations. 497 */ 498 static Declaration.Scoped enum_(Position pos, String name, Declaration... decls) { 499 List<Declaration> declList = Stream.of(decls).collect(Collectors.toList()); 500 return new DeclarationImpl.ScopedImpl(Declaration.Scoped.Kind.ENUM, declList, name, pos); 501 } 502 503 /** 504 * Creates a new enum declaration with given name, layout and member declarations. 505 * @param pos the enum declaration position. 506 * @param name the enum declaration name. 507 * @param layout the enum declaration layout. 508 * @param decls the enum declaration member declarations. 509 * @return a new enum declaration with given name, layout and member declarations. 510 */ 511 static Declaration.Scoped enum_(Position pos, String name, MemoryLayout layout, Declaration... decls) { 512 List<Declaration> declList = Stream.of(decls).collect(Collectors.toList()); 513 return new DeclarationImpl.ScopedImpl(Declaration.Scoped.Kind.ENUM, layout, declList, name, pos); 514 } 515 516 /** 517 * Creates a new function declaration with given name, type and parameter declarations. 518 * @param pos the function declaration position. 519 * @param name the function declaration name. 520 * @param type the function declaration type. 521 * @param params the function declaration parameter declarations. 522 * @return a new function declaration with given name, type and parameter declarations. 523 */ 524 static Declaration.Function function(Position pos, String name, Type.Function type, Declaration.Variable... params) { 525 List<Variable> paramList = Stream.of(params).collect(Collectors.toList()); 526 return new DeclarationImpl.FunctionImpl(type, paramList, name, pos); 527 } 528 529 /** 530 * Creates a new typedef declaration with given name and declared type. 531 * @param pos the typedef declaration position. 532 * @param name the typedef declaration name. 533 * @param type the typedef type 534 * @return a new type declaration with given name and declared type. 535 */ 536 static Declaration.Typedef typedef(Position pos, String name, Type type) { 537 return new DeclarationImpl.TypedefImpl(type, name, pos, null); 538 } 539 }