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