1 /*
2 * Copyright (c) 2014, 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
26 package com.sun.tools.javac.comp;
27
28 import java.util.ArrayList;
29
30 import com.sun.source.tree.LambdaExpressionTree;
31 import com.sun.tools.javac.code.Source;
32 import com.sun.tools.javac.code.Source.Feature;
33 import com.sun.tools.javac.code.Type;
34 import com.sun.tools.javac.code.Types;
35 import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext;
36 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
37 import com.sun.tools.javac.tree.JCTree;
38 import com.sun.tools.javac.tree.JCTree.JCBlock;
39 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
40 import com.sun.tools.javac.tree.JCTree.JCDoWhileLoop;
41 import com.sun.tools.javac.tree.JCTree.JCEnhancedForLoop;
42 import com.sun.tools.javac.tree.JCTree.JCForLoop;
43 import com.sun.tools.javac.tree.JCTree.JCIf;
44 import com.sun.tools.javac.tree.JCTree.JCLambda;
45 import com.sun.tools.javac.tree.JCTree.JCLambda.ParameterKind;
46 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
47 import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
48 import com.sun.tools.javac.tree.JCTree.JCNewClass;
49 import com.sun.tools.javac.tree.JCTree.JCStatement;
50 import com.sun.tools.javac.tree.JCTree.JCSwitch;
51 import com.sun.tools.javac.tree.JCTree.JCTypeApply;
52 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
53 import com.sun.tools.javac.tree.JCTree.JCWhileLoop;
54 import com.sun.tools.javac.tree.JCTree.Tag;
55 import com.sun.tools.javac.tree.TreeCopier;
56 import com.sun.tools.javac.tree.TreeInfo;
57 import com.sun.tools.javac.tree.TreeMaker;
58 import com.sun.tools.javac.tree.TreeScanner;
59 import com.sun.tools.javac.util.Context;
60 import com.sun.tools.javac.util.DefinedBy;
61 import com.sun.tools.javac.util.DefinedBy.Api;
62 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
63 import com.sun.tools.javac.util.List;
64 import com.sun.tools.javac.util.ListBuffer;
65 import com.sun.tools.javac.util.Log;
66 import com.sun.tools.javac.util.Options;
67 import com.sun.tools.javac.util.Position;
68
69 import java.util.EnumSet;
70 import java.util.HashMap;
71 import java.util.Map;
72 import java.util.function.Predicate;
73
74 import com.sun.source.tree.NewClassTree;
75 import com.sun.tools.javac.code.Flags;
76 import com.sun.tools.javac.code.Kinds.Kind;
77 import com.sun.tools.javac.code.Symbol.ClassSymbol;
78 import com.sun.tools.javac.tree.JCTree.JCTry;
79 import com.sun.tools.javac.tree.JCTree.JCUnary;
80 import com.sun.tools.javac.util.Assert;
81 import com.sun.tools.javac.util.DiagnosticSource;
82
83 import static com.sun.tools.javac.code.Flags.GENERATEDCONSTR;
84 import static com.sun.tools.javac.code.TypeTag.CLASS;
85 import static com.sun.tools.javac.tree.JCTree.Tag.APPLY;
86 import static com.sun.tools.javac.tree.JCTree.Tag.FOREACHLOOP;
87 import static com.sun.tools.javac.tree.JCTree.Tag.LABELLED;
88 import static com.sun.tools.javac.tree.JCTree.Tag.METHODDEF;
89 import static com.sun.tools.javac.tree.JCTree.Tag.NEWCLASS;
90 import static com.sun.tools.javac.tree.JCTree.Tag.NULLCHK;
91 import static com.sun.tools.javac.tree.JCTree.Tag.TYPEAPPLY;
92 import static com.sun.tools.javac.tree.JCTree.Tag.VARDEF;
93
94 /**
95 * Helper class for defining custom code analysis, such as finding instance creation expression
96 * that can benefit from diamond syntax.
97 */
98 public class Analyzer {
99 protected static final Context.Key<Analyzer> analyzerKey = new Context.Key<>();
100
101 final Types types;
102 final Log log;
504 * Dummy deferral handler.
505 */
506 DeferredAnalysisHelper flushDeferredHelper = new DeferredAnalysisHelper() {
507 @Override
508 public void queue(RewritingContext rewriting) {
509 //do nothing
510 }
511
512 @Override
513 public void flush(Env<AttrContext> flushEnv) {
514 //do nothing
515 }
516 };
517
518 /**
519 * Simple deferral handler. All tasks belonging to the same outermost class are added to
520 * the same queue. The queue is flushed after flow analysis (only if no error occurred).
521 */
522 DeferredAnalysisHelper queueDeferredHelper = new DeferredAnalysisHelper() {
523
524 Map<ClassSymbol, ArrayList<RewritingContext>> Q = new HashMap<>();
525
526 @Override
527 public void queue(RewritingContext rewriting) {
528 ArrayList<RewritingContext> s = Q.computeIfAbsent(rewriting.env.enclClass.sym.outermostClass(), k -> new ArrayList<>());
529 s.add(rewriting);
530 }
531
532 @Override
533 public void flush(Env<AttrContext> flushEnv) {
534 if (!Q.isEmpty()) {
535 DeferredAnalysisHelper prevHelper = deferredAnalysisHelper;
536 try {
537 deferredAnalysisHelper = flushDeferredHelper;
538 ArrayList<RewritingContext> rewritings = Q.get(flushEnv.enclClass.sym.outermostClass());
539 while (rewritings != null && !rewritings.isEmpty()) {
540 doAnalysis(rewritings.remove(0));
541 }
542 } finally {
543 deferredAnalysisHelper = prevHelper;
544 }
545 }
546 }
547 };
548
549 DeferredAnalysisHelper deferredAnalysisHelper = queueDeferredHelper;
550
551 void doAnalysis(RewritingContext rewriting) {
552 DiagnosticSource prevSource = log.currentSource();
553 LocalCacheContext localCacheContext = argumentAttr.withLocalCacheContext();
554 try {
555 log.useSource(rewriting.env.toplevel.getSourceFile());
556
557 JCStatement treeToAnalyze = (JCStatement)rewriting.originalTree;
558 if (rewriting.env.info.scope.owner.kind == Kind.TYP) {
559 //add a block to hoist potential dangling variable declarations
560 treeToAnalyze = make.at(Position.NOPOS)
|
1 /*
2 * Copyright (c) 2014, 2018, 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
26 package com.sun.tools.javac.comp;
27
28 import java.util.ArrayDeque;
29 import java.util.EnumSet;
30 import java.util.HashMap;
31 import java.util.Map;
32 import java.util.Queue;
33 import java.util.function.Predicate;
34
35 import com.sun.source.tree.LambdaExpressionTree;
36 import com.sun.source.tree.NewClassTree;
37 import com.sun.tools.javac.code.Flags;
38 import com.sun.tools.javac.code.Kinds.Kind;
39 import com.sun.tools.javac.code.Source;
40 import com.sun.tools.javac.code.Source.Feature;
41 import com.sun.tools.javac.code.Symbol.ClassSymbol;
42 import com.sun.tools.javac.code.Type;
43 import com.sun.tools.javac.code.Types;
44 import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext;
45 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
46 import com.sun.tools.javac.tree.JCTree;
47 import com.sun.tools.javac.tree.JCTree.JCBlock;
48 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
49 import com.sun.tools.javac.tree.JCTree.JCDoWhileLoop;
50 import com.sun.tools.javac.tree.JCTree.JCEnhancedForLoop;
51 import com.sun.tools.javac.tree.JCTree.JCForLoop;
52 import com.sun.tools.javac.tree.JCTree.JCIf;
53 import com.sun.tools.javac.tree.JCTree.JCLambda;
54 import com.sun.tools.javac.tree.JCTree.JCLambda.ParameterKind;
55 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
56 import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
57 import com.sun.tools.javac.tree.JCTree.JCNewClass;
58 import com.sun.tools.javac.tree.JCTree.JCStatement;
59 import com.sun.tools.javac.tree.JCTree.JCSwitch;
60 import com.sun.tools.javac.tree.JCTree.JCTry;
61 import com.sun.tools.javac.tree.JCTree.JCTypeApply;
62 import com.sun.tools.javac.tree.JCTree.JCUnary;
63 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
64 import com.sun.tools.javac.tree.JCTree.JCWhileLoop;
65 import com.sun.tools.javac.tree.JCTree.Tag;
66 import com.sun.tools.javac.tree.TreeCopier;
67 import com.sun.tools.javac.tree.TreeInfo;
68 import com.sun.tools.javac.tree.TreeMaker;
69 import com.sun.tools.javac.tree.TreeScanner;
70 import com.sun.tools.javac.util.Assert;
71 import com.sun.tools.javac.util.Context;
72 import com.sun.tools.javac.util.DefinedBy;
73 import com.sun.tools.javac.util.DefinedBy.Api;
74 import com.sun.tools.javac.util.DiagnosticSource;
75 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
76 import com.sun.tools.javac.util.List;
77 import com.sun.tools.javac.util.ListBuffer;
78 import com.sun.tools.javac.util.Log;
79 import com.sun.tools.javac.util.Options;
80 import com.sun.tools.javac.util.Position;
81
82 import static com.sun.tools.javac.code.Flags.GENERATEDCONSTR;
83 import static com.sun.tools.javac.code.TypeTag.CLASS;
84 import static com.sun.tools.javac.tree.JCTree.Tag.APPLY;
85 import static com.sun.tools.javac.tree.JCTree.Tag.FOREACHLOOP;
86 import static com.sun.tools.javac.tree.JCTree.Tag.LABELLED;
87 import static com.sun.tools.javac.tree.JCTree.Tag.METHODDEF;
88 import static com.sun.tools.javac.tree.JCTree.Tag.NEWCLASS;
89 import static com.sun.tools.javac.tree.JCTree.Tag.NULLCHK;
90 import static com.sun.tools.javac.tree.JCTree.Tag.TYPEAPPLY;
91 import static com.sun.tools.javac.tree.JCTree.Tag.VARDEF;
92
93 /**
94 * Helper class for defining custom code analysis, such as finding instance creation expression
95 * that can benefit from diamond syntax.
96 */
97 public class Analyzer {
98 protected static final Context.Key<Analyzer> analyzerKey = new Context.Key<>();
99
100 final Types types;
101 final Log log;
503 * Dummy deferral handler.
504 */
505 DeferredAnalysisHelper flushDeferredHelper = new DeferredAnalysisHelper() {
506 @Override
507 public void queue(RewritingContext rewriting) {
508 //do nothing
509 }
510
511 @Override
512 public void flush(Env<AttrContext> flushEnv) {
513 //do nothing
514 }
515 };
516
517 /**
518 * Simple deferral handler. All tasks belonging to the same outermost class are added to
519 * the same queue. The queue is flushed after flow analysis (only if no error occurred).
520 */
521 DeferredAnalysisHelper queueDeferredHelper = new DeferredAnalysisHelper() {
522
523 Map<ClassSymbol, Queue<RewritingContext>> Q = new HashMap<>();
524
525 @Override
526 public void queue(RewritingContext rewriting) {
527 Queue<RewritingContext> s = Q.computeIfAbsent(rewriting.env.enclClass.sym.outermostClass(), k -> new ArrayDeque<>());
528 s.add(rewriting);
529 }
530
531 @Override
532 public void flush(Env<AttrContext> flushEnv) {
533 if (!Q.isEmpty()) {
534 DeferredAnalysisHelper prevHelper = deferredAnalysisHelper;
535 try {
536 deferredAnalysisHelper = flushDeferredHelper;
537 Queue<RewritingContext> rewritings = Q.get(flushEnv.enclClass.sym.outermostClass());
538 while (rewritings != null && !rewritings.isEmpty()) {
539 doAnalysis(rewritings.remove());
540 }
541 } finally {
542 deferredAnalysisHelper = prevHelper;
543 }
544 }
545 }
546 };
547
548 DeferredAnalysisHelper deferredAnalysisHelper = queueDeferredHelper;
549
550 void doAnalysis(RewritingContext rewriting) {
551 DiagnosticSource prevSource = log.currentSource();
552 LocalCacheContext localCacheContext = argumentAttr.withLocalCacheContext();
553 try {
554 log.useSource(rewriting.env.toplevel.getSourceFile());
555
556 JCStatement treeToAnalyze = (JCStatement)rewriting.originalTree;
557 if (rewriting.env.info.scope.owner.kind == Kind.TYP) {
558 //add a block to hoist potential dangling variable declarations
559 treeToAnalyze = make.at(Position.NOPOS)
|