1 /* 2 * Copyright (c) 2009, 2019, 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 package com.sun.tools.javac.code; 27 28 import java.util.Collections; 29 import java.util.EnumSet; 30 import java.util.Locale; 31 import java.util.Set; 32 33 import javax.lang.model.element.ModuleElement; 34 import javax.lang.model.element.ModuleElement.DirectiveVisitor; 35 36 import com.sun.tools.javac.api.Messages; 37 import com.sun.tools.javac.code.Symbol.ClassSymbol; 38 import com.sun.tools.javac.code.Symbol.ModuleSymbol; 39 import com.sun.tools.javac.code.Symbol.PackageSymbol; 40 import com.sun.tools.javac.util.DefinedBy; 41 import com.sun.tools.javac.util.DefinedBy.Api; 42 import com.sun.tools.javac.util.List; 43 44 45 /** 46 * Root class for the directives that may appear in module compilation units. 47 * 48 * <p><b>This is NOT part of any supported API. 49 * If you write code that depends on this, you do so at your own risk. 50 * This code and its internal interfaces are subject to change or 51 * deletion without notice.</b> 52 */ 53 public abstract class Directive implements ModuleElement.Directive { 54 55 /** Flags for RequiresDirective. */ 56 public enum RequiresFlag { 57 TRANSITIVE(0x0020), 58 STATIC_PHASE(0x0040), 59 SYNTHETIC(0x1000), 60 MANDATED(0x8000), 61 EXTRA(0x10000); 62 63 // overkill? move to ClassWriter? value(Set<RequiresFlag> s)64 public static int value(Set<RequiresFlag> s) { 65 int v = 0; 66 for (RequiresFlag f: s) 67 v |= f.value; 68 return v; 69 } 70 RequiresFlag(int value)71 RequiresFlag(int value) { 72 this.value = value; 73 } 74 75 public final int value; 76 77 @Override toString()78 public String toString() { 79 return String.format("ACC_%s (0x%04x", name(), value); 80 } 81 } 82 83 /** Flags for ExportsDirective. */ 84 public enum ExportsFlag { 85 SYNTHETIC(0x1000), 86 MANDATED(0x8000); 87 88 // overkill? move to ClassWriter? value(Set<ExportsFlag> s)89 public static int value(Set<ExportsFlag> s) { 90 int v = 0; 91 for (ExportsFlag f: s) 92 v |= f.value; 93 return v; 94 } 95 ExportsFlag(int value)96 ExportsFlag(int value) { 97 this.value = value; 98 } 99 100 public final int value; 101 } 102 103 /** 104 * 'exports' Package ';' 105 * 'exports' Package 'to' ModuleList ';' 106 */ 107 public static class ExportsDirective extends Directive 108 implements ModuleElement.ExportsDirective { 109 public final PackageSymbol packge; 110 public final List<ModuleSymbol> modules; 111 public final Set<ExportsFlag> flags; 112 ExportsDirective(PackageSymbol packge, List<ModuleSymbol> modules)113 public ExportsDirective(PackageSymbol packge, List<ModuleSymbol> modules) { 114 this(packge, modules, EnumSet.noneOf(ExportsFlag.class)); 115 } 116 ExportsDirective(PackageSymbol packge, List<ModuleSymbol> modules, Set<ExportsFlag> flags)117 public ExportsDirective(PackageSymbol packge, List<ModuleSymbol> modules, Set<ExportsFlag> flags) { 118 this.packge = packge; 119 this.modules = modules; 120 this.flags = flags; 121 } 122 123 @Override @DefinedBy(Api.LANGUAGE_MODEL) getKind()124 public ModuleElement.DirectiveKind getKind() { 125 return ModuleElement.DirectiveKind.EXPORTS; 126 } 127 128 @Override @DefinedBy(Api.LANGUAGE_MODEL) getPackage()129 public PackageSymbol getPackage() { 130 return packge; 131 } 132 133 @Override @DefinedBy(Api.LANGUAGE_MODEL) getTargetModules()134 public java.util.List<ModuleSymbol> getTargetModules() { 135 return modules == null 136 ? null 137 : Collections.unmodifiableList(modules); 138 } 139 140 @Override toString()141 public String toString() { 142 if (modules == null) 143 return "Exports[" + packge + "]"; 144 else 145 return "Exports[" + packge + ":" + modules + "]"; 146 } 147 148 @Override @DefinedBy(Api.LANGUAGE_MODEL) accept(DirectiveVisitor<R, P> v, P p)149 public <R, P> R accept(DirectiveVisitor<R, P> v, P p) { 150 return v.visitExports(this, p); 151 } 152 } 153 154 /** Flags for OpensDirective. */ 155 public enum OpensFlag { 156 SYNTHETIC(0x1000), 157 MANDATED(0x8000); 158 159 // overkill? move to ClassWriter? value(Set<OpensFlag> s)160 public static int value(Set<OpensFlag> s) { 161 int v = 0; 162 for (OpensFlag f: s) 163 v |= f.value; 164 return v; 165 } 166 OpensFlag(int value)167 OpensFlag(int value) { 168 this.value = value; 169 } 170 171 public final int value; 172 } 173 174 /** 175 * 'opens' Package ';' 176 * 'opens' Package 'to' ModuleList ';' 177 */ 178 public static class OpensDirective extends Directive 179 implements ModuleElement.OpensDirective { 180 public final PackageSymbol packge; 181 public final List<ModuleSymbol> modules; 182 public final Set<OpensFlag> flags; 183 OpensDirective(PackageSymbol packge, List<ModuleSymbol> modules)184 public OpensDirective(PackageSymbol packge, List<ModuleSymbol> modules) { 185 this(packge, modules, EnumSet.noneOf(OpensFlag.class)); 186 } 187 OpensDirective(PackageSymbol packge, List<ModuleSymbol> modules, Set<OpensFlag> flags)188 public OpensDirective(PackageSymbol packge, List<ModuleSymbol> modules, Set<OpensFlag> flags) { 189 this.packge = packge; 190 this.modules = modules; 191 this.flags = flags; 192 } 193 194 @Override @DefinedBy(Api.LANGUAGE_MODEL) getKind()195 public ModuleElement.DirectiveKind getKind() { 196 return ModuleElement.DirectiveKind.OPENS; 197 } 198 199 @Override @DefinedBy(Api.LANGUAGE_MODEL) getPackage()200 public PackageSymbol getPackage() { 201 return packge; 202 } 203 204 @Override @DefinedBy(Api.LANGUAGE_MODEL) getTargetModules()205 public java.util.List<ModuleSymbol> getTargetModules() { 206 return modules == null 207 ? null 208 : Collections.unmodifiableList(modules); 209 } 210 211 @Override toString()212 public String toString() { 213 if (modules == null) 214 return "Opens[" + packge + "]"; 215 else 216 return "Opens[" + packge + ":" + modules + "]"; 217 } 218 219 @Override @DefinedBy(Api.LANGUAGE_MODEL) accept(DirectiveVisitor<R, P> v, P p)220 public <R, P> R accept(DirectiveVisitor<R, P> v, P p) { 221 return v.visitOpens(this, p); 222 } 223 } 224 225 /** 226 * 'provides' ServiceName 'with' QualifiedIdentifier ';' 227 */ 228 public static class ProvidesDirective extends Directive 229 implements ModuleElement.ProvidesDirective { 230 public final ClassSymbol service; 231 public final List<ClassSymbol> impls; 232 ProvidesDirective(ClassSymbol service, List<ClassSymbol> impls)233 public ProvidesDirective(ClassSymbol service, List<ClassSymbol> impls) { 234 this.service = service; 235 this.impls = impls; 236 } 237 238 @Override @DefinedBy(Api.LANGUAGE_MODEL) getKind()239 public ModuleElement.DirectiveKind getKind() { 240 return ModuleElement.DirectiveKind.PROVIDES; 241 } 242 243 @Override @DefinedBy(Api.LANGUAGE_MODEL) getService()244 public ClassSymbol getService() { 245 return service; 246 } 247 248 @Override @DefinedBy(Api.LANGUAGE_MODEL) getImplementations()249 public List<ClassSymbol> getImplementations() { 250 return impls; 251 } 252 253 @Override toString()254 public String toString() { 255 return "Provides[" + service + "," + impls + "]"; 256 } 257 258 @Override @DefinedBy(Api.LANGUAGE_MODEL) accept(DirectiveVisitor<R, P> v, P p)259 public <R, P> R accept(DirectiveVisitor<R, P> v, P p) { 260 return v.visitProvides(this, p); 261 } 262 263 // TODO: delete? 264 @Override equals(Object obj)265 public boolean equals(Object obj) { 266 if (!(obj instanceof ProvidesDirective)) { 267 return false; 268 } 269 ProvidesDirective other = (ProvidesDirective)obj; 270 return service == other.service && impls.equals(other.impls); 271 } 272 273 // TODO: delete? 274 @Override hashCode()275 public int hashCode() { 276 return service.hashCode() * 31 + impls.hashCode() * 37; 277 } 278 } 279 280 /** 281 * 'requires' ('static' | 'transitive')* ModuleName ';' 282 */ 283 public static class RequiresDirective extends Directive 284 implements ModuleElement.RequiresDirective { 285 public final ModuleSymbol module; 286 public final Set<RequiresFlag> flags; 287 RequiresDirective(ModuleSymbol module)288 public RequiresDirective(ModuleSymbol module) { 289 this(module, EnumSet.noneOf(RequiresFlag.class)); 290 } 291 RequiresDirective(ModuleSymbol module, Set<RequiresFlag> flags)292 public RequiresDirective(ModuleSymbol module, Set<RequiresFlag> flags) { 293 this.module = module; 294 this.flags = flags; 295 } 296 297 @Override @DefinedBy(Api.LANGUAGE_MODEL) getKind()298 public ModuleElement.DirectiveKind getKind() { 299 return ModuleElement.DirectiveKind.REQUIRES; 300 } 301 302 @Override @DefinedBy(Api.LANGUAGE_MODEL) isStatic()303 public boolean isStatic() { 304 return flags.contains(RequiresFlag.STATIC_PHASE); 305 } 306 307 @Override @DefinedBy(Api.LANGUAGE_MODEL) isTransitive()308 public boolean isTransitive() { 309 return flags.contains(RequiresFlag.TRANSITIVE); 310 } 311 312 @Override @DefinedBy(Api.LANGUAGE_MODEL) getDependency()313 public ModuleSymbol getDependency() { 314 return module; 315 } 316 317 @Override toString()318 public String toString() { 319 return "Requires[" + flags + "," + module + "]"; 320 } 321 322 @Override @DefinedBy(Api.LANGUAGE_MODEL) accept(DirectiveVisitor<R, P> v, P p)323 public <R, P> R accept(DirectiveVisitor<R, P> v, P p) { 324 return v.visitRequires(this, p); 325 } 326 } 327 328 /** 329 * 'uses' ServiceName ';' 330 */ 331 public static class UsesDirective extends Directive 332 implements ModuleElement.UsesDirective { 333 public final ClassSymbol service; 334 UsesDirective(ClassSymbol service)335 public UsesDirective(ClassSymbol service) { 336 this.service = service; 337 } 338 339 @Override @DefinedBy(Api.LANGUAGE_MODEL) getKind()340 public ModuleElement.DirectiveKind getKind() { 341 return ModuleElement.DirectiveKind.USES; 342 } 343 344 @Override @DefinedBy(Api.LANGUAGE_MODEL) getService()345 public ClassSymbol getService() { 346 return service; 347 } 348 349 @Override toString()350 public String toString() { 351 return "Uses[" + service + "]"; 352 } 353 354 @Override @DefinedBy(Api.LANGUAGE_MODEL) accept(DirectiveVisitor<R, P> v, P p)355 public <R, P> R accept(DirectiveVisitor<R, P> v, P p) { 356 return v.visitUses(this, p); 357 } 358 359 // TODO: delete? 360 @Override equals(Object obj)361 public boolean equals(Object obj) { 362 if (!(obj instanceof UsesDirective)) { 363 return false; 364 } 365 UsesDirective other = (UsesDirective)obj; 366 return service == other.service; 367 } 368 369 // TODO: delete? 370 @Override hashCode()371 public int hashCode() { 372 return service.hashCode() * 31; 373 } 374 } 375 } 376