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