JavaParser Source Viewer

Home|JavaParser/com/github/javaparser/ast/validator/chunks/ModifierValidator.java
1/*
2 * Copyright (C) 2007-2010 JĂșlio Vilmar Gesser.
3 * Copyright (C) 2011, 2013-2020 The JavaParser Team.
4 *
5 * This file is part of JavaParser.
6 *
7 * JavaParser can be used either under the terms of
8 * a) the GNU Lesser General Public License as published by
9 *     the Free Software Foundation, either version 3 of the License, or
10 *     (at your option) any later version.
11 * b) the terms of the Apache License
12 *
13 * You should have received a copy of both licenses in LICENCE.LGPL and
14 * LICENCE.APACHE. Please refer to those files for details.
15 *
16 * JavaParser is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU Lesser General Public License for more details.
20 */
21
22package com.github.javaparser.ast.validator.chunks;
23
24import com.github.javaparser.ast.Modifier;
25import com.github.javaparser.ast.body.*;
26import com.github.javaparser.ast.expr.LambdaExpr;
27import com.github.javaparser.ast.expr.VariableDeclarationExpr;
28import com.github.javaparser.ast.modules.ModuleRequiresDirective;
29import com.github.javaparser.ast.nodeTypes.NodeWithModifiers;
30import com.github.javaparser.ast.nodeTypes.NodeWithTokenRange;
31import com.github.javaparser.ast.stmt.CatchClause;
32import com.github.javaparser.ast.validator.ProblemReporter;
33import com.github.javaparser.ast.validator.VisitorValidator;
34import com.github.javaparser.utils.SeparatedItemStringBuilder;
35
36import java.util.ArrayList;
37import java.util.List;
38
39import static com.github.javaparser.ast.Modifier.Keyword.*;
40import static java.util.Arrays.asList;
41
42
43/**
44 * Verifies that only allowed modifiers are used where modifiers are expected.
45 */
46public class ModifierValidator extends VisitorValidator {
47    private final Modifier.Keyword[] interfaceWithNothingSpecial = new Modifier.Keyword[]{PUBLICPROTECTEDABSTRACTFINALSYNCHRONIZEDNATIVESTRICTFP};
48    private final Modifier.Keyword[] interfaceWithStaticAndDefault = new Modifier.Keyword[]{PUBLICPROTECTEDABSTRACTSTATICFINALSYNCHRONIZEDNATIVESTRICTFPDEFAULT};
49    private final Modifier.Keyword[] interfaceWithStaticAndDefaultAndPrivate = new Modifier.Keyword[]{PUBLICPROTECTEDPRIVATEABSTRACTSTATICFINALSYNCHRONIZEDNATIVESTRICTFPDEFAULT};
50
51    private final boolean hasStrictfp;
52    private final boolean hasDefaultAndStaticInterfaceMethods;
53    private final boolean hasPrivateInterfaceMethods;
54
55    public ModifierValidator(boolean hasStrictfpboolean hasDefaultAndStaticInterfaceMethodsboolean hasPrivateInterfaceMethods) {
56        this.hasStrictfp = hasStrictfp;
57        this.hasDefaultAndStaticInterfaceMethods = hasDefaultAndStaticInterfaceMethods;
58        this.hasPrivateInterfaceMethods = hasPrivateInterfaceMethods;
59    }
60
61    @Override
62    public void visit(ClassOrInterfaceDeclaration nProblemReporter reporter) {
63        if (n.isInterface()) {
64            validateInterfaceModifiers(nreporter);
65        } else {
66            validateClassModifiers(nreporter);
67        }
68        super.visit(nreporter);
69    }
70
71    private void validateClassModifiers(ClassOrInterfaceDeclaration nProblemReporter reporter) {
72        if (n.isTopLevelType()) {
73            validateModifiers(nreporterPUBLICABSTRACTFINALSTRICTFP);
74        } else if (n.isNestedType()) {
75            validateModifiers(nreporterPUBLICPROTECTEDPRIVATEABSTRACTSTATICFINALSTRICTFP);
76        } else if (n.isLocalClassDeclaration()) {
77            validateModifiers(nreporterABSTRACTFINALSTRICTFP);
78        }
79    }
80
81    private void validateInterfaceModifiers(TypeDeclaration<?> nProblemReporter reporter) {
82        if (n.isTopLevelType()) {
83            validateModifiers(nreporterPUBLICABSTRACTSTRICTFP);
84        } else if (n.isNestedType()) {
85            validateModifiers(nreporterPUBLICPROTECTEDPRIVATEABSTRACTSTATICSTRICTFP);
86        }
87    }
88
89    @Override
90    public void visit(EnumDeclaration nProblemReporter reporter) {
91        if (n.isTopLevelType()) {
92            validateModifiers(nreporterPUBLICSTRICTFP);
93        } else if (n.isNestedType()) {
94            validateModifiers(nreporterPUBLICPROTECTEDPRIVATESTATICSTRICTFP);
95        }
96        super.visit(nreporter);
97    }
98
99    @Override
100    public void visit(AnnotationDeclaration nProblemReporter reporter) {
101        validateInterfaceModifiers(nreporter);
102        super.visit(nreporter);
103    }
104
105    @Override
106    public void visit(AnnotationMemberDeclaration nProblemReporter reporter) {
107        validateModifiers(nreporterPUBLICABSTRACT);
108        super.visit(nreporter);
109    }
110
111    @Override
112    public void visit(ConstructorDeclaration nProblemReporter reporter) {
113        validateModifiers(nreporterPUBLICPROTECTEDPRIVATE);
114        n.getParameters().forEach(p -> validateModifiers(preporterFINAL));
115        super.visit(nreporter);
116    }
117
118    @Override
119    public void visit(FieldDeclaration nProblemReporter reporter) {
120        validateModifiers(nreporterPUBLICPROTECTEDPRIVATESTATICFINALTRANSIENTVOLATILE);
121        super.visit(nreporter);
122    }
123
124    @Override
125    public void visit(MethodDeclaration nProblemReporter reporter) {
126        if (n.isAbstract()) {
127            final SeparatedItemStringBuilder builder = new SeparatedItemStringBuilder("Cannot be 'abstract' and also '""', '""'.");
128            for (Modifier.Keyword m : asList(PRIVATESTATICFINALNATIVESTRICTFPSYNCHRONIZED)) {
129                if (n.hasModifier(m)) {
130                    builder.append(m.asString());
131                }
132            }
133            if (builder.hasItems()) {
134                reporter.report(nbuilder.toString());
135            }
136        }
137        if (n.getParentNode().isPresent()) {
138            if (n.getParentNode().get() instanceof ClassOrInterfaceDeclaration) {
139                if (((ClassOrInterfaceDeclarationn.getParentNode().get()).isInterface()) {
140                    if (hasDefaultAndStaticInterfaceMethods) {
141                        if (hasPrivateInterfaceMethods) {
142                            validateModifiers(nreporterinterfaceWithStaticAndDefaultAndPrivate);
143                        } else {
144                            validateModifiers(nreporterinterfaceWithStaticAndDefault);
145                        }
146                    } else {
147                        validateModifiers(nreporterinterfaceWithNothingSpecial);
148                    }
149                } else {
150                    validateModifiers(nreporterPUBLICPROTECTEDPRIVATEABSTRACTSTATICFINALSYNCHRONIZEDNATIVESTRICTFP);
151                }
152            }
153        }
154        n.getParameters().forEach(p -> validateModifiers(preporterFINAL));
155        super.visit(nreporter);
156    }
157
158    @Override
159    public void visit(LambdaExpr nProblemReporter reporter) {
160        n.getParameters().forEach(p -> {
161            // Final is not allowed on inferred parameters, but those get caught by the parser.
162            validateModifiers(preporterFINAL);
163        });
164        super.visit(nreporter);
165    }
166
167    @Override
168    public void visit(CatchClause nProblemReporter reporter) {
169        validateModifiers(n.getParameter(), reporterFINAL);
170        super.visit(nreporter);
171    }
172
173    @Override
174    public void visit(VariableDeclarationExpr nProblemReporter reporter) {
175        validateModifiers(nreporterFINAL);
176        super.visit(nreporter);
177    }
178
179    @Override
180    public void visit(ModuleRequiresDirective nProblemReporter reporter) {
181        validateModifiers(nreporterTRANSITIVESTATIC);
182        super.visit(nreporter);
183    }
184
185    private <T extends NodeWithModifiers<?> & NodeWithTokenRange<?>> void validateModifiers(T nProblemReporter reporterModifier.Keyword... allowedModifiers) {
186        validateAtMostOneOf(nreporterPUBLICPROTECTEDPRIVATE);
187        validateAtMostOneOf(nreporterFINALABSTRACT);
188        if (hasStrictfp) {
189            validateAtMostOneOf(nreporterNATIVESTRICTFP);
190        } else {
191            allowedModifiers = removeModifierFromArray(STRICTFPallowedModifiers);
192        }
193        for (Modifier m : n.getModifiers()) {
194            if (!arrayContains(allowedModifiersm.getKeyword())) {
195                reporter.report(n"'%s' is not allowed here."m.getKeyword().asString());
196            }
197        }
198    }
199
200    private Modifier.Keyword[] removeModifierFromArray(Modifier.Keyword mModifier.Keyword[] allowedModifiers) {
201        final List<Modifier.KeywordnewModifiers = new ArrayList<>(asList(allowedModifiers));
202        newModifiers.remove(m);
203        allowedModifiers = newModifiers.toArray(new Modifier.Keyword[0]);
204        return allowedModifiers;
205    }
206
207    private boolean arrayContains(Object[] itemsObject searchItem) {
208        for (Object o : items) {
209            if (o == searchItem) {
210                return true;
211            }
212        }
213        return false;
214    }
215
216    private <T extends NodeWithModifiers<?> & NodeWithTokenRange<?>> void validateAtMostOneOf(T tProblemReporter reporterModifier.Keyword... modifiers) {
217        List<Modifier.KeywordfoundModifiers = new ArrayList<>();
218        for (Modifier.Keyword m : modifiers) {
219            if (t.hasModifier(m)) {
220                foundModifiers.add(m);
221            }
222        }
223        if (foundModifiers.size() > 1) {
224            SeparatedItemStringBuilder builder = new SeparatedItemStringBuilder("Can have only one of '""', '""'.");
225            for (Modifier.Keyword m : foundModifiers) {
226                builder.append(m.asString());
227            }
228            reporter.report(tbuilder.toString());
229        }
230    }
231
232}
233
MembersX
ModifierValidator:validateClassModifiers
ModifierValidator:interfaceWithNothingSpecial
ModifierValidator:hasDefaultAndStaticInterfaceMethods
ModifierValidator:removeModifierFromArray:Block:newModifiers
ModifierValidator:ModifierValidator
ModifierValidator:visit
ModifierValidator:interfaceWithStaticAndDefaultAndPrivate
ModifierValidator:hasStrictfp
ModifierValidator:validateInterfaceModifiers
ModifierValidator:validateAtMostOneOf:Block:foundModifiers
ModifierValidator:hasPrivateInterfaceMethods
ModifierValidator:interfaceWithStaticAndDefault
ModifierValidator:validateAtMostOneOf:Block:Block:builder
ModifierValidator:visit:Block:Block:builder
ModifierValidator:validateModifiers
ModifierValidator:validateAtMostOneOf
ModifierValidator:removeModifierFromArray
ModifierValidator:arrayContains
Members
X