1 11 package org.eclipse.jdt.apt.core.internal.env; 12 13 import java.util.ArrayList ; 14 import java.util.Collection ; 15 import java.util.Collections ; 16 import java.util.HashMap ; 17 import java.util.HashSet ; 18 import java.util.List ; 19 import java.util.Map ; 20 import java.util.Set ; 21 22 import org.eclipse.core.resources.IFile; 23 import org.eclipse.core.runtime.CoreException; 24 import org.eclipse.core.runtime.IStatus; 25 import org.eclipse.jdt.apt.core.env.EclipseAnnotationProcessorEnvironment; 26 import org.eclipse.jdt.apt.core.env.Phase; 27 import org.eclipse.jdt.apt.core.internal.AptPlugin; 28 import org.eclipse.jdt.apt.core.internal.declaration.EclipseMirrorObject; 29 import org.eclipse.jdt.apt.core.internal.declaration.TypeDeclarationImpl; 30 import org.eclipse.jdt.apt.core.internal.env.MessagerImpl.Severity; 31 import org.eclipse.jdt.apt.core.internal.util.Factory; 32 import org.eclipse.jdt.apt.core.internal.util.Visitors.AnnotationVisitor; 33 import org.eclipse.jdt.apt.core.util.AptPreferenceConstants; 34 import org.eclipse.jdt.apt.core.util.EclipseMessager; 35 import org.eclipse.jdt.core.ICompilationUnit; 36 import org.eclipse.jdt.core.IJavaProject; 37 import org.eclipse.jdt.core.JavaConventions; 38 import org.eclipse.jdt.core.JavaCore; 39 import org.eclipse.jdt.core.compiler.BuildContext; 40 import org.eclipse.jdt.core.compiler.CategorizedProblem; 41 import org.eclipse.jdt.core.compiler.ReconcileContext; 42 import org.eclipse.jdt.core.dom.ASTRequestor; 43 import org.eclipse.jdt.core.dom.Annotation; 44 import org.eclipse.jdt.core.dom.CompilationUnit; 45 import org.eclipse.jdt.core.dom.ITypeBinding; 46 47 import com.sun.mirror.apt.AnnotationProcessorFactory; 48 import com.sun.mirror.apt.AnnotationProcessorListener; 49 import com.sun.mirror.apt.Filer; 50 import com.sun.mirror.declaration.AnnotationTypeDeclaration; 51 52 53 public abstract class AbstractCompilationEnv 54 extends BaseProcessorEnv 55 implements EclipseAnnotationProcessorEnvironment { 56 57 private final static String RTTG_ENABLED_DASH_A_OPTION = "-A" + AptPreferenceConstants.RTTG_ENABLED_OPTION; 60 private Set <AnnotationProcessorListener> _listeners = null; 61 62 protected List <APTProblem> _problems = new ArrayList <APTProblem>(); 63 private boolean _isClosed = false; 64 65 EnvCallback _callback; 66 67 private Set <IFile> _allGeneratedSourceFiles = new HashSet <IFile>(); 68 private Set <IFile> _modifiedGeneratedSourceFiles = new HashSet <IFile>(); 69 70 73 protected ASTRequestor _requestor; 74 75 78 private AnnotationProcessorFactory _currentProcessorFactory = null; 79 80 public static interface EnvCallback { 81 public void run(AbstractCompilationEnv env); 82 } 83 84 public static void newReconcileEnv(ReconcileContext reconcileContext, EnvCallback callback) 85 { 86 assert reconcileContext != null : "reconcile context is null"; ReconcileEnv env = ReconcileEnv.newEnv(reconcileContext); 88 env._callback = callback; 89 env.openPipeline(); 90 } 91 92 public static void newBuildEnv( 93 BuildContext[] filesWithAnnotations, 94 final BuildContext[] additionalFiles, 95 IJavaProject javaProj, 96 EnvCallback callback) 97 { 98 assert filesWithAnnotations != null : "missing files"; 100 BuildEnv env = new BuildEnv(filesWithAnnotations, additionalFiles, javaProj); 102 env._callback = callback; 103 env.createASTs(filesWithAnnotations); 104 } 105 106 AbstractCompilationEnv( 107 CompilationUnit compilationUnit, 108 IFile file, 109 IJavaProject javaProj, 110 Phase phase) 111 { 112 super(compilationUnit, file, javaProj, phase); 113 } 114 115 @Override 116 protected ITypeBinding getTypeBindingFromKey(String key, ICompilationUnit unit) { 117 return (ITypeBinding)_requestor.createBindings(new String [] {key})[0]; 118 } 119 120 public void addListener(AnnotationProcessorListener listener) 121 { 122 checkValid(); 123 if(_listeners == null ) 124 _listeners = new HashSet <AnnotationProcessorListener>(); 125 _listeners.add(listener); 126 } 127 128 public void removeListener(AnnotationProcessorListener listener) 129 { 130 checkValid(); 131 if( _listeners == null ) return; 132 _listeners.remove(listener); 133 } 134 135 public Set <AnnotationProcessorListener> getProcessorListeners() 136 { 137 if( _listeners == null ) 138 return Collections.emptySet(); 139 return new HashSet <AnnotationProcessorListener>(_listeners); 142 } 143 144 public Map <String , String > getOptions() 145 { 146 final HashMap <String , String > options = new HashMap <String , String >(_options); 147 options.put("phase", getPhase().toString()); return options; 149 } 150 151 abstract public CompilationUnit getASTFrom(final IFile file); 152 153 public CompilationUnit getAST(){ 154 return _astRoot; 155 } 156 157 public EclipseMessager getMessager() 158 { 159 checkValid(); 160 return new MessagerImpl(this); 161 } 162 163 abstract void addMessage( 164 IFile resource, 165 int start, 166 int end, 167 Severity severity, 168 String msg, 169 int line, 170 String [] arguments); 171 172 public List <? extends CategorizedProblem> getProblems(){ 173 checkValid(); 174 if( !_problems.isEmpty() ) 175 EnvUtil.updateProblemLength(_problems, getAstCompilationUnit()); 176 return _problems; 177 } 178 179 APTProblem createProblem( 180 IFile resource, 181 int start, 182 int end, 183 Severity severity, 184 String msg, 185 int line, 186 String [] arguments) 187 { 188 final APTProblem newProblem = 191 new APTProblem(msg, severity, resource, start, end-1, line, arguments); 192 return newProblem; 193 } 194 195 public abstract Filer getFiler(); 196 197 public void addGeneratedSourceFile( IFile f, boolean contentsChanged ) { 198 if (!f.toString().endsWith(".java")) { throw new IllegalArgumentException ("Source files must be java source files, and end with .java"); } 201 202 boolean addedToAll = _allGeneratedSourceFiles.add(f); 203 boolean addedToMod = false; 204 if (contentsChanged) 205 addedToMod = _modifiedGeneratedSourceFiles.add(f); 206 if (AptPlugin.DEBUG_COMPILATION_ENV) { 207 AptPlugin.trace("add generated file " + f + " to env " + this + "; addToAll = " + addedToAll + "; addToMod = " + addedToMod + "; contentsChanged = " + contentsChanged); } 211 } 212 213 public void addGeneratedNonSourceFile(final IFile file) { 214 _allGeneratedSourceFiles.add(file); 215 } 216 217 public Set <IFile> getAllGeneratedFiles() { 218 return _allGeneratedSourceFiles; 219 } 220 221 public Set <IFile> getModifiedGeneratedFiles() { 222 return _modifiedGeneratedSourceFiles; 223 } 224 225 229 public boolean hasGeneratedSourceFiles(){ return !_allGeneratedSourceFiles.isEmpty(); } 230 231 232 235 public Map <String , AnnotationTypeDeclaration> getAnnotationTypes() 236 { 237 checkValid(); 238 final List <Annotation> instances = new ArrayList <Annotation>(); 239 final Map <String , AnnotationTypeDeclaration> decls = 240 new HashMap <String , AnnotationTypeDeclaration>(); 241 final AnnotationVisitor visitor = new AnnotationVisitor(instances); 242 _astRoot.accept(visitor); 243 244 for (int instanceIndex=0, size = instances.size(); instanceIndex < size; instanceIndex++) { 245 final Annotation instance = instances.get(instanceIndex); 246 final ITypeBinding annoType = instance.resolveTypeBinding(); 247 if (annoType == null) 248 continue; 249 final TypeDeclarationImpl decl = 250 Factory.createReferenceType(annoType, this); 251 if (decl.kind() == EclipseMirrorObject.MirrorKind.TYPE_ANNOTATION){ 252 final AnnotationTypeDeclaration annoDecl = (AnnotationTypeDeclaration)decl; 253 decls.put(annoDecl.getQualifiedName(), annoDecl); 254 } 255 } 256 257 return decls; 258 } 259 260 void checkValid() 261 { 262 if( _isClosed ) 263 throw new IllegalStateException ("Environment has expired"); } 265 266 protected void completedProcessing() { 268 _modifiedGeneratedSourceFiles.clear(); 269 } 270 271 public void close(){ 272 if (isClosed()) 273 return; 274 if(_listeners != null) 275 _listeners.clear(); 276 _problems = null; 277 _typeCache.clear(); 278 _packageRootsCache = null; 279 _isClosed = true; 280 _callback = null; 281 _requestor = null; 282 _allGeneratedSourceFiles = null; 283 _modifiedGeneratedSourceFiles = null; 284 if (AptPlugin.DEBUG_COMPILATION_ENV) AptPlugin.trace( 285 "closed env " + this); } 287 288 boolean isClosed(){ return _isClosed; } 289 290 295 @SuppressWarnings ("unchecked") 296 public void validateTypeName(String typeName) throws CoreException 297 { 298 Map <String , String > options = getJavaProject().getOptions(true); 299 String sourceLevel = options.get(JavaCore.COMPILER_SOURCE); 300 String complianceLevel = options.get(JavaCore.COMPILER_COMPLIANCE); 301 IStatus status = JavaConventions.validateJavaTypeName(typeName, sourceLevel, complianceLevel); 302 if (status.matches(IStatus.ERROR)) { 303 throw new CoreException(status); 304 } 305 } 306 307 public AnnotationProcessorFactory getCurrentProcessorFactory() { 308 return _currentProcessorFactory; 309 } 310 311 public void setCurrentProcessorFactory(AnnotationProcessorFactory processor) 312 { 313 _currentProcessorFactory = processor; 314 } 315 316 public boolean currentProcessorSupportsRTTG() 317 { 318 AnnotationProcessorFactory factory = getCurrentProcessorFactory(); 319 if (null == factory) { 320 return false; 321 } 322 Collection <String > options = factory.supportedOptions(); 323 if (null == options) { 324 return false; 325 } 326 return options.contains(AptPreferenceConstants.RTTG_ENABLED_OPTION) || 327 options.contains(RTTG_ENABLED_DASH_A_OPTION); 328 } 329 330 } 331 | Popular Tags |