1 /*
2  * Copyright (c) 2016, 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.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 
26 package jdk.tools.jaotc;
27 
28 import java.util.HashSet;
29 import java.util.Iterator;
30 import java.util.regex.Pattern;
31 
32 import jdk.vm.ci.meta.ResolvedJavaMethod;
33 
34 /**
35  * A class encapsulating any user-specified compilation restrictions.
36  */
37 final class CompilationSpec {
38 
39     /**
40      * Set of method names to restrict compilation to.
41      */
42     private HashSet<String> compileOnlyStrings = new HashSet<>();
43     private HashSet<Pattern> compileOnlyPatterns = new HashSet<>();
44 
45     /**
46      * Set of method names that should be excluded from compilation.
47      */
48     private HashSet<String> excludeStrings = new HashSet<>();
49     private HashSet<Pattern> excludePatterns = new HashSet<>();
50 
51     /**
52      * Add a {@code compileOnly} directive to the compile-only list.
53      *
54      * @param pattern regex or non-regex pattern string
55      */
addCompileOnlyPattern(String pattern)56     void addCompileOnlyPattern(String pattern) {
57         if (pattern.contains("*")) {
58             compileOnlyPatterns.add(Pattern.compile(pattern));
59         } else {
60             compileOnlyStrings.add(pattern);
61         }
62     }
63 
64     /**
65      * Add an {@code exclude} directive to the exclude list.
66      *
67      * @param pattern regex or non-regex pattern string
68      */
addExcludePattern(String pattern)69     void addExcludePattern(String pattern) {
70         if (pattern.contains("*")) {
71             excludePatterns.add(Pattern.compile(pattern));
72         } else {
73             excludeStrings.add(pattern);
74         }
75     }
76 
77     /**
78      * Check if a given method is part of a restrictive compilation.
79      *
80      * @param method method to be checked
81      * @return true or false
82      */
shouldCompileMethod(ResolvedJavaMethod method)83     boolean shouldCompileMethod(ResolvedJavaMethod method) {
84         if (compileWithRestrictions()) {
85             // If there are user-specified compileOnly patterns, default action
86             // is not to compile the method.
87             boolean compileMethod = compileOnlyStrings.isEmpty() && compileOnlyPatterns.isEmpty();
88 
89             // Check if the method matches with any of the specified compileOnly patterns.
90             String methodName = JavaMethodInfo.uniqueMethodName(method);
91 
92             // compileOnly
93             if (!compileMethod) {
94                 compileMethod = compileOnlyStrings.contains(methodName);
95             }
96             if (!compileMethod) {
97                 Iterator<Pattern> it = compileOnlyPatterns.iterator();
98                 while (!compileMethod && it.hasNext()) {
99                     Pattern pattern = it.next();
100                     compileMethod = pattern.matcher(methodName).matches();
101                 }
102             }
103 
104             // exclude
105             if (compileMethod) {
106                 compileMethod = !excludeStrings.contains(methodName);
107             }
108             if (compileMethod) {
109                 Iterator<Pattern> it = excludePatterns.iterator();
110                 while (compileMethod && it.hasNext()) {
111                     Pattern pattern = it.next();
112                     compileMethod = !(pattern.matcher(methodName).matches());
113                 }
114             }
115             return compileMethod;
116         }
117         return true;
118     }
119 
120     /**
121      * Return true if compilation restrictions are specified.
122      */
compileWithRestrictions()123     private boolean compileWithRestrictions() {
124         return !(compileOnlyStrings.isEmpty() && compileOnlyPatterns.isEmpty() && excludeStrings.isEmpty() && excludePatterns.isEmpty());
125     }
126 
127 }
128