Categories:
Audio (13)
Biotech (29)
Bytecode (36)
Database (77)
Framework (7)
Game (7)
General (507)
Graphics (53)
I/O (35)
IDE (2)
JAR Tools (102)
JavaBeans (21)
JDBC (121)
JDK (426)
JSP (20)
Logging (108)
Mail (58)
Messaging (8)
Network (84)
PDF (97)
Report (7)
Scripting (84)
Security (32)
Server (121)
Servlet (26)
SOAP (24)
Testing (54)
Web (15)
XML (322)
Collections:
Other Resources:
JDK 11 jdk.compiler.jmod - Compiler Tool
JDK 11 jdk.compiler.jmod is the JMOD file for JDK 11 Compiler tool,
which can be invoked by the "javac" command.
JDK 11 Compiler tool compiled class files are stored in \fyicenter\jdk-11.0.1\jmods\jdk.compiler.jmod.
JDK 11 Compiler tool compiled class files are also linked and stored in the \fyicenter\jdk-11.0.1\lib\modules JImage file.
JDK 11 Compiler source code files are stored in \fyicenter\jdk-11.0.1\lib\src.zip\jdk.compiler.
You can click and view the content of each source code file in the list below.
✍: FYIcenter
⏎ com/sun/tools/javac/comp/Analyzer.java
/*
* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package com.sun.tools.javac.comp;
import java.util.ArrayList;
import com.sun.source.tree.LambdaExpressionTree;
import com.sun.tools.javac.code.Source;
import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext;
import com.sun.tools.javac.resources.CompilerProperties.Warnings;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCBlock;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCDoWhileLoop;
import com.sun.tools.javac.tree.JCTree.JCEnhancedForLoop;
import com.sun.tools.javac.tree.JCTree.JCForLoop;
import com.sun.tools.javac.tree.JCTree.JCIf;
import com.sun.tools.javac.tree.JCTree.JCLambda;
import com.sun.tools.javac.tree.JCTree.JCLambda.ParameterKind;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
import com.sun.tools.javac.tree.JCTree.JCNewClass;
import com.sun.tools.javac.tree.JCTree.JCStatement;
import com.sun.tools.javac.tree.JCTree.JCSwitch;
import com.sun.tools.javac.tree.JCTree.JCTypeApply;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.tree.JCTree.JCWhileLoop;
import com.sun.tools.javac.tree.JCTree.Tag;
import com.sun.tools.javac.tree.TreeCopier;
import com.sun.tools.javac.tree.TreeInfo;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.TreeScanner;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Options;
import com.sun.tools.javac.util.Position;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;
import com.sun.source.tree.NewClassTree;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Kinds.Kind;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.tree.JCTree.JCTry;
import com.sun.tools.javac.tree.JCTree.JCUnary;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.DiagnosticSource;
import static com.sun.tools.javac.code.Flags.GENERATEDCONSTR;
import static com.sun.tools.javac.code.TypeTag.CLASS;
import static com.sun.tools.javac.tree.JCTree.Tag.APPLY;
import static com.sun.tools.javac.tree.JCTree.Tag.FOREACHLOOP;
import static com.sun.tools.javac.tree.JCTree.Tag.LABELLED;
import static com.sun.tools.javac.tree.JCTree.Tag.METHODDEF;
import static com.sun.tools.javac.tree.JCTree.Tag.NEWCLASS;
import static com.sun.tools.javac.tree.JCTree.Tag.NULLCHK;
import static com.sun.tools.javac.tree.JCTree.Tag.TYPEAPPLY;
import static com.sun.tools.javac.tree.JCTree.Tag.VARDEF;
/**
* Helper class for defining custom code analysis, such as finding instance creation expression
* that can benefit from diamond syntax.
*/
public class Analyzer {
protected static final Context.Key<Analyzer> analyzerKey = new Context.Key<>();
final Types types;
final Log log;
final Attr attr;
final DeferredAttr deferredAttr;
final ArgumentAttr argumentAttr;
final TreeMaker make;
final AnalyzerCopier copier;
private final boolean allowDiamondWithAnonymousClassCreation;
final EnumSet<AnalyzerMode> analyzerModes;
public static Analyzer instance(Context context) {
Analyzer instance = context.get(analyzerKey);
if (instance == null)
instance = new Analyzer(context);
return instance;
}
protected Analyzer(Context context) {
context.put(analyzerKey, this);
types = Types.instance(context);
log = Log.instance(context);
attr = Attr.instance(context);
deferredAttr = DeferredAttr.instance(context);
argumentAttr = ArgumentAttr.instance(context);
make = TreeMaker.instance(context);
copier = new AnalyzerCopier();
Options options = Options.instance(context);
String findOpt = options.get("find");
//parse modes
Source source = Source.instance(context);
allowDiamondWithAnonymousClassCreation = Feature.DIAMOND_WITH_ANONYMOUS_CLASS_CREATION.allowedInSource(source);
analyzerModes = AnalyzerMode.getAnalyzerModes(findOpt, source);
}
/**
* This enum defines supported analyzer modes, as well as defining the logic for decoding
* the {@code -XDfind} option.
*/
enum AnalyzerMode {
DIAMOND("diamond", Feature.DIAMOND),
LAMBDA("lambda", Feature.LAMBDA),
METHOD("method", Feature.GRAPH_INFERENCE),
LOCAL("local", Feature.LOCAL_VARIABLE_TYPE_INFERENCE);
final String opt;
final Feature feature;
AnalyzerMode(String opt, Feature feature) {
this.opt = opt;
this.feature = feature;
}
/**
* This method is used to parse the {@code find} option.
* Possible modes are separated by colon; a mode can be excluded by
* prepending '-' to its name. Finally, the special mode 'all' can be used to
* add all modes to the resulting enum.
*/
static EnumSet<AnalyzerMode> getAnalyzerModes(String opt, Source source) {
if (opt == null) {
return EnumSet.noneOf(AnalyzerMode.class);
}
List<String> modes = List.from(opt.split(","));
EnumSet<AnalyzerMode> res = EnumSet.noneOf(AnalyzerMode.class);
if (modes.contains("all")) {
res = EnumSet.allOf(AnalyzerMode.class);
}
for (AnalyzerMode mode : values()) {
if (modes.contains(mode.opt)) {
res.add(mode);
} else if (modes.contains("-" + mode.opt) || !mode.feature.allowedInSource(source)) {
res.remove(mode);
}
}
return res;
}
}
/**
* A statement analyzer is a work-unit that matches certain AST nodes (of given type {@code S}),
* rewrites them to different AST nodes (of type {@code T}) and then generates some meaningful
* messages in case the analysis has been successful.
*/
abstract class StatementAnalyzer<S extends JCTree, T extends JCTree> {
AnalyzerMode mode;
JCTree.Tag tag;
StatementAnalyzer(AnalyzerMode mode, Tag tag) {
this.mode = mode;
this.tag = tag;
}
/**
* Is this analyzer allowed to run?
*/
boolean isEnabled() {
return analyzerModes.contains(mode);
}
/**
* Should this analyzer be rewriting the given tree?
*/
abstract boolean match(S tree);
/**
* Rewrite a given AST node into a new one(s)
*/
abstract List<T> rewrite(S oldTree);
/**
* Entry-point for comparing results and generating diagnostics.
*/
abstract void process(S oldTree, T newTree, boolean hasErrors);
}
/**
* This analyzer checks if generic instance creation expression can use diamond syntax.
*/
class DiamondInitializer extends StatementAnalyzer<JCNewClass, JCNewClass> {
DiamondInitializer() {
super(AnalyzerMode.DIAMOND, NEWCLASS);
}
@Override
boolean match(JCNewClass tree) {
return tree.clazz.hasTag(TYPEAPPLY) &&
!TreeInfo.isDiamond(tree) &&
(tree.def == null || allowDiamondWithAnonymousClassCreation);
}
@Override
List<JCNewClass> rewrite(JCNewClass oldTree) {
if (oldTree.clazz.hasTag(TYPEAPPLY)) {
JCNewClass nc = copier.copy(oldTree);
((JCTypeApply)nc.clazz).arguments = List.nil();
return List.of(nc);
} else {
return List.of(oldTree);
}
}
@Override
void process(JCNewClass oldTree, JCNewClass newTree, boolean hasErrors) {
if (!hasErrors) {
List<Type> inferredArgs, explicitArgs;
if (oldTree.def != null) {
inferredArgs = newTree.def.implementing.nonEmpty()
? newTree.def.implementing.get(0).type.getTypeArguments()
: newTree.def.extending.type.getTypeArguments();
explicitArgs = oldTree.def.implementing.nonEmpty()
? oldTree.def.implementing.get(0).type.getTypeArguments()
: oldTree.def.extending.type.getTypeArguments();
} else {
inferredArgs = newTree.type.getTypeArguments();
explicitArgs = oldTree.type.getTypeArguments();
}
for (Type t : inferredArgs) {
if (!types.isSameType(t, explicitArgs.head)) {
return;
}
explicitArgs = explicitArgs.tail;
}
//exact match
log.warning(oldTree.clazz, Warnings.DiamondRedundantArgs);
}
}
}
/**
* This analyzer checks if anonymous instance creation expression can replaced by lambda.
*/
class LambdaAnalyzer extends StatementAnalyzer<JCNewClass, JCLambda> {
LambdaAnalyzer() {
super(AnalyzerMode.LAMBDA, NEWCLASS);
}
@Override
boolean match (JCNewClass tree){
Type clazztype = tree.clazz.type;
return tree.def != null &&
clazztype.hasTag(CLASS) &&
types.isFunctionalInterface(clazztype.tsym) &&
decls(tree.def).length() == 1;
}
//where
private List<JCTree> decls(JCClassDecl decl) {
ListBuffer<JCTree> decls = new ListBuffer<>();
for (JCTree t : decl.defs) {
if (t.hasTag(METHODDEF)) {
JCMethodDecl md = (JCMethodDecl)t;
if ((md.getModifiers().flags & GENERATEDCONSTR) == 0) {
decls.add(md);
}
} else {
decls.add(t);
}
}
return decls.toList();
}
@Override
List<JCLambda> rewrite(JCNewClass oldTree){
JCMethodDecl md = (JCMethodDecl)copier.copy(decls(oldTree.def).head);
List<JCVariableDecl> params = md.params;
JCBlock body = md.body;
JCLambda newTree = make.at(oldTree).Lambda(params, body);
return List.of(newTree);
}
@Override
void process (JCNewClass oldTree, JCLambda newTree, boolean hasErrors){
if (!hasErrors) {
log.warning(oldTree.def, Warnings.PotentialLambdaFound);
}
}
}
/**
* This analyzer checks if generic method call has redundant type arguments.
*/
class RedundantTypeArgAnalyzer extends StatementAnalyzer<JCMethodInvocation, JCMethodInvocation> {
RedundantTypeArgAnalyzer() {
super(AnalyzerMode.METHOD, APPLY);
}
@Override
boolean match (JCMethodInvocation tree){
return tree.typeargs != null &&
tree.typeargs.nonEmpty();
}
@Override
List<JCMethodInvocation> rewrite(JCMethodInvocation oldTree){
JCMethodInvocation app = copier.copy(oldTree);
app.typeargs = List.nil();
return List.of(app);
}
@Override
void process (JCMethodInvocation oldTree, JCMethodInvocation newTree, boolean hasErrors){
if (!hasErrors) {
//exact match
log.warning(oldTree, Warnings.MethodRedundantTypeargs);
}
}
}
/**
* Base class for local variable inference analyzers.
*/
abstract class RedundantLocalVarTypeAnalyzerBase<X extends JCStatement> extends StatementAnalyzer<X, X> {
RedundantLocalVarTypeAnalyzerBase(JCTree.Tag tag) {
super(AnalyzerMode.LOCAL, tag);
}
boolean isImplicitlyTyped(JCVariableDecl decl) {
return decl.vartype.pos == Position.NOPOS;
}
/**
* Map a variable tree into a new declaration using implicit type.
*/
JCVariableDecl rewriteVarType(JCVariableDecl oldTree) {
JCVariableDecl newTree = copier.copy(oldTree);
newTree.vartype = null;
return newTree;
}
/**
* Analyze results of local variable inference.
*/
void processVar(JCVariableDecl oldTree, JCVariableDecl newTree, boolean hasErrors) {
if (!hasErrors) {
if (types.isSameType(oldTree.type, newTree.type)) {
log.warning(oldTree, Warnings.LocalRedundantType);
}
}
}
}
/**
* This analyzer checks if a local variable declaration has redundant type.
*/
class RedundantLocalVarTypeAnalyzer extends RedundantLocalVarTypeAnalyzerBase<JCVariableDecl> {
RedundantLocalVarTypeAnalyzer() {
super(VARDEF);
}
boolean match(JCVariableDecl tree){
return tree.sym.owner.kind == Kind.MTH &&
tree.init != null && !isImplicitlyTyped(tree) &&
attr.canInferLocalVarType(tree) == null;
}
@Override
List<JCVariableDecl> rewrite(JCVariableDecl oldTree) {
return List.of(rewriteVarType(oldTree));
}
@Override
void process(JCVariableDecl oldTree, JCVariableDecl newTree, boolean hasErrors){
processVar(oldTree, newTree, hasErrors);
}
}
/**
* This analyzer checks if a for each variable declaration has redundant type.
*/
class RedundantLocalVarTypeAnalyzerForEach extends RedundantLocalVarTypeAnalyzerBase<JCEnhancedForLoop> {
RedundantLocalVarTypeAnalyzerForEach() {
super(FOREACHLOOP);
}
@Override
boolean match(JCEnhancedForLoop tree){
return !isImplicitlyTyped(tree.var);
}
@Override
List<JCEnhancedForLoop> rewrite(JCEnhancedForLoop oldTree) {
JCEnhancedForLoop newTree = copier.copy(oldTree);
newTree.var = rewriteVarType(oldTree.var);
newTree.body = make.at(oldTree.body).Block(0, List.nil());
return List.of(newTree);
}
@Override
void process(JCEnhancedForLoop oldTree, JCEnhancedForLoop newTree, boolean hasErrors){
processVar(oldTree.var, newTree.var, hasErrors);
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
StatementAnalyzer<JCTree, JCTree>[] analyzers = new StatementAnalyzer[] {
new DiamondInitializer(),
new LambdaAnalyzer(),
new RedundantTypeArgAnalyzer(),
new RedundantLocalVarTypeAnalyzer(),
new RedundantLocalVarTypeAnalyzerForEach()
};
/**
* Create a copy of Env if needed.
*/
Env<AttrContext> copyEnvIfNeeded(JCTree tree, Env<AttrContext> env) {
if (!analyzerModes.isEmpty() &&
!env.info.isSpeculative &&
TreeInfo.isStatement(tree) &&
!tree.hasTag(LABELLED)) {
Env<AttrContext> analyzeEnv =
env.dup(env.tree, env.info.dup(env.info.scope.dupUnshared(env.info.scope.owner)));
analyzeEnv.info.returnResult = analyzeEnv.info.returnResult != null ?
attr.new ResultInfo(analyzeEnv.info.returnResult.pkind,
analyzeEnv.info.returnResult.pt) : null;
return analyzeEnv;
} else {
return null;
}
}
/**
* Analyze an AST node if needed.
*/
void analyzeIfNeeded(JCTree tree, Env<AttrContext> env) {
if (env != null) {
JCStatement stmt = (JCStatement)tree;
analyze(stmt, env);
}
}
/**
* Analyze an AST node; this involves collecting a list of all the nodes that needs rewriting,
* and speculatively type-check the rewritten code to compare results against previously attributed code.
*/
void analyze(JCStatement statement, Env<AttrContext> env) {
StatementScanner statementScanner = new StatementScanner(statement, env);
statementScanner.scan();
if (!statementScanner.rewritings.isEmpty()) {
for (RewritingContext rewriting : statementScanner.rewritings) {
deferredAnalysisHelper.queue(rewriting);
}
}
}
/**
* Helper interface to handle deferral of analysis tasks.
*/
interface DeferredAnalysisHelper {
/**
* Add a new analysis task to the queue.
*/
void queue(RewritingContext rewriting);
/**
* Flush queue with given attribution env.
*/
void flush(Env<AttrContext> flushEnv);
}
/**
* Dummy deferral handler.
*/
DeferredAnalysisHelper flushDeferredHelper = new DeferredAnalysisHelper() {
@Override
public void queue(RewritingContext rewriting) {
//do nothing
}
@Override
public void flush(Env<AttrContext> flushEnv) {
//do nothing
}
};
/**
* Simple deferral handler. All tasks belonging to the same outermost class are added to
* the same queue. The queue is flushed after flow analysis (only if no error occurred).
*/
DeferredAnalysisHelper queueDeferredHelper = new DeferredAnalysisHelper() {
Map<ClassSymbol, ArrayList<RewritingContext>> Q = new HashMap<>();
@Override
public void queue(RewritingContext rewriting) {
ArrayList<RewritingContext> s = Q.computeIfAbsent(rewriting.env.enclClass.sym.outermostClass(), k -> new ArrayList<>());
s.add(rewriting);
}
@Override
public void flush(Env<AttrContext> flushEnv) {
if (!Q.isEmpty()) {
DeferredAnalysisHelper prevHelper = deferredAnalysisHelper;
try {
deferredAnalysisHelper = flushDeferredHelper;
ArrayList<RewritingContext> rewritings = Q.get(flushEnv.enclClass.sym.outermostClass());
while (rewritings != null && !rewritings.isEmpty()) {
doAnalysis(rewritings.remove(0));
}
} finally {
deferredAnalysisHelper = prevHelper;
}
}
}
};
DeferredAnalysisHelper deferredAnalysisHelper = queueDeferredHelper;
void doAnalysis(RewritingContext rewriting) {
DiagnosticSource prevSource = log.currentSource();
LocalCacheContext localCacheContext = argumentAttr.withLocalCacheContext();
try {
log.useSource(rewriting.env.toplevel.getSourceFile());
JCStatement treeToAnalyze = (JCStatement)rewriting.originalTree;
if (rewriting.env.info.scope.owner.kind == Kind.TYP) {
//add a block to hoist potential dangling variable declarations
treeToAnalyze = make.at(Position.NOPOS)
.Block(Flags.SYNTHETIC, List.of((JCStatement)rewriting.originalTree));
}
//TODO: to further refine the analysis, try all rewriting combinations
deferredAttr.attribSpeculative(treeToAnalyze, rewriting.env, attr.statInfo, new TreeRewriter(rewriting),
t -> rewriting.diagHandler(), argumentAttr.withLocalCacheContext());
rewriting.analyzer.process(rewriting.oldTree, rewriting.replacement, rewriting.erroneous);
} catch (Throwable ex) {
Assert.error("Analyzer error when processing: " + rewriting.originalTree);
} finally {
log.useSource(prevSource.getFile());
localCacheContext.leave();
}
}
public void flush(Env<AttrContext> flushEnv) {
deferredAnalysisHelper.flush(flushEnv);
}
/**
* Subclass of {@link com.sun.tools.javac.tree.TreeScanner} which visit AST-nodes w/o crossing
* statement boundaries.
*/
class StatementScanner extends TreeScanner {
/** Tree rewritings (generated by analyzers). */
ListBuffer<RewritingContext> rewritings = new ListBuffer<>();
JCTree originalTree;
Env<AttrContext> env;
StatementScanner(JCTree originalTree, Env<AttrContext> env) {
this.originalTree = originalTree;
this.env = attr.copyEnv(env);
}
public void scan() {
scan(originalTree);
}
@Override
@SuppressWarnings("unchecked")
public void scan(JCTree tree) {
if (tree != null) {
for (StatementAnalyzer<JCTree, JCTree> analyzer : analyzers) {
if (analyzer.isEnabled() &&
tree.hasTag(analyzer.tag) &&
analyzer.match(tree)) {
for (JCTree t : analyzer.rewrite(tree)) {
rewritings.add(new RewritingContext(originalTree, tree, t, analyzer, env));
}
break; //TODO: cover cases where multiple matching analyzers are found
}
}
}
super.scan(tree);
}
@Override
public void visitClassDef(JCClassDecl tree) {
//do nothing (prevents seeing same stuff twice)
}
@Override
public void visitMethodDef(JCMethodDecl tree) {
//do nothing (prevents seeing same stuff twice)
}
@Override
public void visitBlock(JCBlock tree) {
//do nothing (prevents seeing same stuff twice)
}
@Override
public void visitSwitch(JCSwitch tree) {
scan(tree.getExpression());
}
@Override
public void visitForLoop(JCForLoop tree) {
//skip body and var decl (to prevents same statements to be analyzed twice)
scan(tree.getCondition());
scan(tree.getUpdate());
}
@Override
public void visitTry(JCTry tree) {
//skip resources (to prevents same statements to be analyzed twice)
scan(tree.getBlock());
scan(tree.getCatches());
scan(tree.getFinallyBlock());
}
@Override
public void visitForeachLoop(JCEnhancedForLoop tree) {
//skip body (to prevents same statements to be analyzed twice)
scan(tree.getExpression());
}
@Override
public void visitWhileLoop(JCWhileLoop tree) {
//skip body (to prevents same statements to be analyzed twice)
scan(tree.getCondition());
}
@Override
public void visitDoLoop(JCDoWhileLoop tree) {
//skip body (to prevents same statements to be analyzed twice)
scan(tree.getCondition());
}
@Override
public void visitIf(JCIf tree) {
//skip body (to prevents same statements to be analyzed twice)
scan(tree.getCondition());
}
}
class RewritingContext {
// the whole tree being analyzed
JCTree originalTree;
// a subtree, old tree, that will be rewritten
JCTree oldTree;
// the replacement for the old tree
JCTree replacement;
// did the compiler find any error
boolean erroneous;
// the env
Env<AttrContext> env;
// the corresponding analyzer
StatementAnalyzer<JCTree, JCTree> analyzer;
RewritingContext(
JCTree originalTree,
JCTree oldTree,
JCTree replacement,
StatementAnalyzer<JCTree, JCTree> analyzer,
Env<AttrContext> env) {
this.originalTree = originalTree;
this.oldTree = oldTree;
this.replacement = replacement;
this.analyzer = analyzer;
this.env = attr.copyEnv(env);
/* this is a temporary workaround that should be removed once we have a truly independent
* clone operation
*/
if (originalTree.hasTag(VARDEF)) {
// avoid redefinition clashes
this.env.info.scope.remove(((JCVariableDecl)originalTree).sym);
}
}
/**
* Simple deferred diagnostic handler which filters out all messages and keep track of errors.
*/
Log.DeferredDiagnosticHandler diagHandler() {
return new Log.DeferredDiagnosticHandler(log, d -> {
if (d.getType() == DiagnosticType.ERROR) {
erroneous = true;
}
return true;
});
}
}
/**
* Subclass of TreeCopier that maps nodes matched by analyzers onto new AST nodes.
*/
class AnalyzerCopier extends TreeCopier<Void> {
public AnalyzerCopier() {
super(make);
}
@Override @DefinedBy(Api.COMPILER_TREE)
public JCTree visitLambdaExpression(LambdaExpressionTree node, Void _unused) {
JCLambda oldLambda = (JCLambda)node;
JCLambda newLambda = (JCLambda)super.visitLambdaExpression(node, _unused);
if (oldLambda.paramKind == ParameterKind.IMPLICIT) {
//reset implicit lambda parameters (whose type might have been set during attr)
newLambda.paramKind = ParameterKind.IMPLICIT;
newLambda.params.forEach(p -> p.vartype = null);
}
return newLambda;
}
@Override @DefinedBy(Api.COMPILER_TREE)
public JCTree visitNewClass(NewClassTree node, Void aVoid) {
JCNewClass oldNewClazz = (JCNewClass)node;
JCNewClass newNewClazz = (JCNewClass)super.visitNewClass(node, aVoid);
if (!oldNewClazz.args.isEmpty() && oldNewClazz.args.head.hasTag(NULLCHK)) {
//workaround to Attr generating trees
newNewClazz.encl = ((JCUnary)newNewClazz.args.head).arg;
newNewClazz.args = newNewClazz.args.tail;
}
return newNewClazz;
}
}
class TreeRewriter extends AnalyzerCopier {
RewritingContext rewriting;
TreeRewriter(RewritingContext rewriting) {
this.rewriting = rewriting;
}
@Override
@SuppressWarnings("unchecked")
public <Z extends JCTree> Z copy(Z tree, Void _unused) {
Z newTree = super.copy(tree, null);
if (tree != null && tree == rewriting.oldTree) {
Assert.checkNonNull(rewriting.replacement);
newTree = (Z)rewriting.replacement;
}
return newTree;
}
}
}
⏎ com/sun/tools/javac/comp/Analyzer.java
Or download all of them as a single archive file:
File name: jdk.compiler-11.0.1-src.zip File size: 1347269 bytes Release date: 2018-11-04 Download
⇒ JDK 11 jdk.crypto.cryptoki.jmod - Crypto KI Module
2020-08-13, ≈179🔥, 0💬
Popular Posts:
JDK 11 jdk.rmic.jmod is the JMOD file for JDK 11 RMI (Remote Method Invocation) Compiler Tool tool, ...
JDK 11 jdk.rmic.jmod is the JMOD file for JDK 11 RMI (Remote Method Invocation) Compiler Tool tool, ...
What JAR files are required to run sax\Counter.java provided in the Apache Xerces package? You can f...
Apache Log4j 1.2 Bridge allows applications coded to use Log4j 1.2 API to use Log4j 2 instead. Bytec...
maven-settings-builder-3 .8.6.jaris the JAR file for Apache Maven 3.8.6 Settings Builder module. Apa...