PublicApiCollector.java revision 2958:27da0c3ac83a
1/* 2 * Copyright (c) 2014, 2015, 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.sjavac.comp.dependencies; 27 28import java.util.Collection; 29import java.util.HashSet; 30import java.util.Map; 31import java.util.Set; 32 33import javax.tools.JavaFileObject; 34 35import com.sun.source.tree.Tree; 36import com.sun.source.util.TaskEvent; 37import com.sun.source.util.TaskListener; 38import com.sun.tools.javac.code.Symbol.ClassSymbol; 39import com.sun.tools.javac.tree.JCTree.JCClassDecl; 40import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; 41import com.sun.tools.javac.util.Context; 42import com.sun.tools.javac.util.DefinedBy; 43import com.sun.tools.javac.util.DefinedBy.Api; 44import com.sun.tools.sjavac.Log; 45import com.sun.tools.sjavac.comp.PubAPIs; 46import com.sun.tools.sjavac.pubapi.PubApi; 47 48 49public class PublicApiCollector implements TaskListener { 50 51 private Context context; 52 private final Set<ClassSymbol> classSymbols = new HashSet<>(); 53 private final Collection<JavaFileObject> explicitJFOs; 54 55 // Result collected upon compilation task finished 56 private Map<String, PubApi> explicitPubApis; 57 private Map<String, PubApi> nonExplicitPubApis; 58 59 public PublicApiCollector(Context context, 60 Collection<JavaFileObject> explicitJFOs) { 61 this.context = context; 62 this.explicitJFOs = explicitJFOs; 63 } 64 65 @Override 66 @DefinedBy(Api.COMPILER_TREE) 67 public void finished(TaskEvent e) { 68 switch (e.getKind()) { 69 case ANALYZE: 70 collectClassSymbols((JCCompilationUnit) e.getCompilationUnit()); 71 break; 72 case COMPILATION: 73 Log.debug("Compilation finished"); 74 Log.debug("Extracting pub APIs for the following symbols:"); 75 for (ClassSymbol cs : classSymbols) 76 Log.debug(" " + cs.fullname); 77 extractPubApis(); 78 79 // Save result for later retrieval. (Important that we do this 80 // before we return from this method, because we may not access 81 // symbols after compilation is finished.) 82 PubAPIs pa = PubAPIs.instance(context); 83 explicitPubApis = pa.getPubapis(explicitJFOs, true); 84 nonExplicitPubApis = pa.getPubapis(explicitJFOs, false); 85 86 Log.debug("done"); 87 break; 88 } 89 } 90 91 private void collectClassSymbols(JCCompilationUnit cu) { 92 for (Tree t : cu.getTypeDecls()) { 93 if (t instanceof JCClassDecl) // Can also be a JCSkip 94 classSymbols.add(((JCClassDecl) t).sym); 95 } 96 } 97 98 private void extractPubApis() { 99 // To handle incremental builds (subsequent sjavac invocations) we need 100 // to keep track of the public API of what we depend upon. 101 // 102 // During the recompilation loop (within a single sjavac invocation) we 103 // need to keep track of public API of what we're compiling to decide if 104 // any dependants needs to be tainted. 105 PubAPIs pubApis = PubAPIs.instance(context); 106 classSymbols.forEach(pubApis::visitPubapi); 107 } 108 109 public Map<String, PubApi> getPubApis(boolean explicit) { 110 return explicit ? explicitPubApis : nonExplicitPubApis; 111 } 112} 113