
lombok.ast.syntaxChecks.StructuralChecks Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lombok.ast Show documentation
Show all versions of lombok.ast Show documentation
An abstract syntax tree for java source code, including a parser and converters to/from ecj (eclipse) and javac.
The newest version!
/*
* Copyright (C) 2010 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package lombok.ast.syntaxChecks;
import static lombok.ast.syntaxChecks.MessageKey.*;
import static lombok.ast.Message.*;
import lombok.ast.AlternateConstructorInvocation;
import lombok.ast.Block;
import lombok.ast.ConstructorDeclaration;
import lombok.ast.InstanceInitializer;
import lombok.ast.MethodDeclaration;
import lombok.ast.Modifiers;
import lombok.ast.Node;
import lombok.ast.Return;
import lombok.ast.Statement;
import lombok.ast.StaticInitializer;
import lombok.ast.SuperConstructorInvocation;
import lombok.ast.Throw;
import lombok.ast.TypeDeclaration;
import lombok.ast.VariableDefinition;
import lombok.ast.VariableDefinitionEntry;
import lombok.ast.template.SyntaxCheck;
@SyntaxCheck
public class StructuralChecks {
public void checkAbstractMembersOnlyInAbstractTypes(MethodDeclaration md) {
Modifiers modifiers = md.astModifiers();
if (modifiers == null) return;
if (!modifiers.isAbstract()) return;
TypeDeclaration parent = md.upUpToTypeDeclaration();
if (parent != null) {
Modifiers modifiersOfParent = parent.astModifiers();
if (modifiersOfParent != null && modifiersOfParent.isAbstract()) return;
md.addMessage(error(MODIFIERS_ABSTRACT_NOT_ALLOWED, "Abstract methods are only allowed in interfaces and abstract classes"));
}
}
public void initializersMustCompleteNormallyStatic(StaticInitializer node) {
initializersMustCompleteNormally(node.rawBody());
}
public void initializersMustCompleteNormallyInstance(InstanceInitializer node) {
initializersMustCompleteNormally(node.rawBody());
}
private void initializersMustCompleteNormally(Node rawBlock) {
if (!(rawBlock instanceof Block)) return;
for (Node s : ((Block)rawBlock).rawContents()) {
if (s instanceof Throw) s.addMessage(error(INITIALIZERS_INITIALIZER_MUST_COMPLETE_NORMALLY, "Initializers may not contain throws statements."));
if (s instanceof Return) s.addMessage(error(INITIALIZERS_INITIALIZER_MUST_COMPLETE_NORMALLY, "Initializers may not contain return statements."));
}
}
public void superConstructorInvocationMustBeFirst(SuperConstructorInvocation node) {
constructorInvocationMustBeFirst(node, "super");
}
public void alternateConstructorInvocationMustBeFirst(AlternateConstructorInvocation node) {
constructorInvocationMustBeFirst(node, "this");
}
private void constructorInvocationMustBeFirst(Statement node, String desc) {
if (node.getParent() == null) return;
Block b = node.upToBlock();
if (b == null || b.upToConstructorDeclaration() == null || b.astContents().first() != node) {
node.addMessage(error(CONSTRUCTOR_INVOCATION_NOT_LEGAL_HERE, "Calling " + desc + " must be the first statement in a constructor."));
return;
}
}
public void varDefOfZero(VariableDefinition node) {
if (node.astVariables().isEmpty()) {
node.addMessage(error(VARIABLEDEFINITION_EMPTY, "Empty variable declaration."));
}
}
public void varargsOnlyLegalOnMethods(VariableDefinition node) {
if (!node.astVarargs()) return;
if (node.getParent() == null) return;
MethodDeclaration md = node.upIfParameterToMethodDeclaration();
ConstructorDeclaration cd = node.upIfParameterToConstructorDeclaration();
Node last;
if (md != null) last = md.astParameters().last();
else if (cd != null) last = cd.astParameters().last();
else last = null;
if (node != last) {
node.addMessage(error(VARIABLEDEFINITION_VARARGS_NOT_LEGAL_HERE, "Varargs are only legal on the last parameter of a constructor or method."));
}
}
public void varargsAndExtendedDimsDontMix(VariableDefinitionEntry node) {
VariableDefinition vd = node.upToVariableDefinition();
if (vd == null) return;
if (node.astArrayDimensions() > 0 && vd.astVarargs()) {
node.addMessage(error(VARIABLEDEFINITIONENTRY_EXTENDED_DIMENSIONS_NOT_LEGAL, "Extended dimensions are not legal on a varargs declaration."));
}
}
public void checkMethodParamsAreSimple(MethodDeclaration md) {
for (Node param : md.rawParameters()) {
BasicChecks.checkVarDefIsSimple(param, param, "method parameters", "parameter");
}
}
public void checkConstructorParamsAreSimple(ConstructorDeclaration cd) {
for (Node param : cd.rawParameters()) {
BasicChecks.checkVarDefIsSimple(param, param, "constructor parameters", "parameter");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy