Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.sonar.java.ast.parser.TreeFactory Maven / Gradle / Ivy
/*
* SonarQube Java
* Copyright (C) 2012 SonarSource
* [email protected]
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.java.ast.parser;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.sonar.java.ast.api.JavaKeyword;
import org.sonar.java.ast.api.JavaPunctuator;
import org.sonar.java.ast.api.JavaTokenType;
import org.sonar.java.model.ArrayDimensionTreeImpl;
import org.sonar.java.model.InternalSyntaxToken;
import org.sonar.java.model.JavaTree;
import org.sonar.java.model.JavaTree.ArrayTypeTreeImpl;
import org.sonar.java.model.JavaTree.CompilationUnitTreeImpl;
import org.sonar.java.model.JavaTree.ImportTreeImpl;
import org.sonar.java.model.JavaTree.PackageDeclarationTreeImpl;
import org.sonar.java.model.JavaTree.ParameterizedTypeTreeImpl;
import org.sonar.java.model.JavaTree.PrimitiveTypeTreeImpl;
import org.sonar.java.model.JavaTree.UnionTypeTreeImpl;
import org.sonar.java.model.JavaTree.WildcardTreeImpl;
import org.sonar.java.model.KindMaps;
import org.sonar.java.model.TypeParameterTreeImpl;
import org.sonar.java.model.declaration.AnnotationTreeImpl;
import org.sonar.java.model.declaration.ClassTreeImpl;
import org.sonar.java.model.declaration.EnumConstantTreeImpl;
import org.sonar.java.model.declaration.MethodTreeImpl;
import org.sonar.java.model.declaration.ModifierKeywordTreeImpl;
import org.sonar.java.model.declaration.ModifiersTreeImpl;
import org.sonar.java.model.declaration.VariableTreeImpl;
import org.sonar.java.model.expression.ArrayAccessExpressionTreeImpl;
import org.sonar.java.model.expression.AssignmentExpressionTreeImpl;
import org.sonar.java.model.expression.BinaryExpressionTreeImpl;
import org.sonar.java.model.expression.ConditionalExpressionTreeImpl;
import org.sonar.java.model.expression.IdentifierTreeImpl;
import org.sonar.java.model.expression.InstanceOfTreeImpl;
import org.sonar.java.model.expression.InternalPostfixUnaryExpression;
import org.sonar.java.model.expression.InternalPrefixUnaryExpression;
import org.sonar.java.model.expression.LambdaExpressionTreeImpl;
import org.sonar.java.model.expression.LiteralTreeImpl;
import org.sonar.java.model.expression.MemberSelectExpressionTreeImpl;
import org.sonar.java.model.expression.MethodInvocationTreeImpl;
import org.sonar.java.model.expression.MethodReferenceTreeImpl;
import org.sonar.java.model.expression.NewArrayTreeImpl;
import org.sonar.java.model.expression.NewClassTreeImpl;
import org.sonar.java.model.expression.ParenthesizedTreeImpl;
import org.sonar.java.model.expression.TypeArgumentListTreeImpl;
import org.sonar.java.model.expression.TypeCastExpressionTreeImpl;
import org.sonar.java.model.statement.AssertStatementTreeImpl;
import org.sonar.java.model.statement.BlockTreeImpl;
import org.sonar.java.model.statement.BreakStatementTreeImpl;
import org.sonar.java.model.statement.CaseGroupTreeImpl;
import org.sonar.java.model.statement.CaseLabelTreeImpl;
import org.sonar.java.model.statement.CatchTreeImpl;
import org.sonar.java.model.statement.ContinueStatementTreeImpl;
import org.sonar.java.model.statement.DoWhileStatementTreeImpl;
import org.sonar.java.model.statement.EmptyStatementTreeImpl;
import org.sonar.java.model.statement.ExpressionStatementTreeImpl;
import org.sonar.java.model.statement.ForEachStatementImpl;
import org.sonar.java.model.statement.ForStatementTreeImpl;
import org.sonar.java.model.statement.IfStatementTreeImpl;
import org.sonar.java.model.statement.LabeledStatementTreeImpl;
import org.sonar.java.model.statement.ReturnStatementTreeImpl;
import org.sonar.java.model.statement.StaticInitializerTreeImpl;
import org.sonar.java.model.statement.SwitchStatementTreeImpl;
import org.sonar.java.model.statement.SynchronizedStatementTreeImpl;
import org.sonar.java.model.statement.ThrowStatementTreeImpl;
import org.sonar.java.model.statement.TryStatementTreeImpl;
import org.sonar.java.model.statement.WhileStatementTreeImpl;
import com.sonar.sslr.api.typed.Optional;
import org.sonar.plugins.java.api.tree.AnnotationTree;
import org.sonar.plugins.java.api.tree.ArrayDimensionTree;
import org.sonar.plugins.java.api.tree.ExpressionTree;
import org.sonar.plugins.java.api.tree.IdentifierTree;
import org.sonar.plugins.java.api.tree.ImportClauseTree;
import org.sonar.plugins.java.api.tree.ListTree;
import org.sonar.plugins.java.api.tree.ModifierTree;
import org.sonar.plugins.java.api.tree.PackageDeclarationTree;
import org.sonar.plugins.java.api.tree.ParameterizedTypeTree;
import org.sonar.plugins.java.api.tree.StatementTree;
import org.sonar.plugins.java.api.tree.SyntaxToken;
import org.sonar.plugins.java.api.tree.Tree;
import org.sonar.plugins.java.api.tree.Tree.Kind;
import org.sonar.plugins.java.api.tree.TypeArguments;
import org.sonar.plugins.java.api.tree.TypeParameterTree;
import org.sonar.plugins.java.api.tree.TypeTree;
import org.sonar.plugins.java.api.tree.VariableTree;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
public class TreeFactory {
private final KindMaps kindMaps = new KindMaps();
public ModifiersTreeImpl modifiers(Optional> modifierNodes) {
if (!modifierNodes.isPresent()) {
return ModifiersTreeImpl.emptyModifiers();
}
return new ModifiersTreeImpl(modifierNodes.get());
}
public ModifierKeywordTreeImpl modifierKeyword(InternalSyntaxToken token) {
JavaKeyword keyword = (JavaKeyword) token.getGrammarRuleKey();
return new ModifierKeywordTreeImpl(kindMaps.getModifier(keyword), token);
}
// Literals
public ExpressionTree literal(InternalSyntaxToken token) {
return new LiteralTreeImpl(kindMaps.getLiteral(token.getGrammarRuleKey()), token);
}
// End of literals
// Compilation unit
public CompilationUnitTreeImpl newCompilationUnit(
JavaTree spacing,
Optional packageDeclaration,
Optional> importDeclarations,
Optional> typeDeclarations,
InternalSyntaxToken eof) {
ImmutableList.Builder imports = ImmutableList.builder();
if (importDeclarations.isPresent()) {
for (ImportClauseTree child : importDeclarations.get()) {
imports.add(child);
}
}
ImmutableList.Builder types = ImmutableList.builder();
if (typeDeclarations.isPresent()) {
for (Tree child : typeDeclarations.get()) {
types.add(child);
}
}
return new CompilationUnitTreeImpl(
packageDeclaration.orNull(),
imports.build(),
types.build(),
eof);
}
public PackageDeclarationTreeImpl newPackageDeclaration(Optional> annotations, InternalSyntaxToken packageToken, ExpressionTree qualifiedIdentifier,
InternalSyntaxToken semicolonToken) {
List annotationList = Collections.emptyList();
if (annotations.isPresent()) {
annotationList = ImmutableList.builder().addAll(annotations.get()).build();
}
return new PackageDeclarationTreeImpl(annotationList, packageToken, qualifiedIdentifier, semicolonToken);
}
public ImportClauseTree newEmptyImport(InternalSyntaxToken semicolonToken) {
return new EmptyStatementTreeImpl(semicolonToken);
}
public ImportTreeImpl newImportDeclaration(InternalSyntaxToken importToken, Optional staticToken, ExpressionTree qualifiedIdentifier,
Optional> dotStar,
InternalSyntaxToken semicolonToken) {
ExpressionTree target = qualifiedIdentifier;
if (dotStar.isPresent()) {
IdentifierTreeImpl identifier = new IdentifierTreeImpl(dotStar.get().second());
InternalSyntaxToken dotToken = dotStar.get().first();
target = new MemberSelectExpressionTreeImpl(qualifiedIdentifier, dotToken, identifier);
}
InternalSyntaxToken staticKeyword = staticToken.orNull();
return new ImportTreeImpl(importToken, staticKeyword, target, semicolonToken);
}
public ClassTreeImpl newTypeDeclaration(ModifiersTreeImpl modifiers, ClassTreeImpl partial) {
return partial.completeModifiers(modifiers);
}
public Tree newEmptyType(InternalSyntaxToken semicolonToken) {
return new EmptyStatementTreeImpl(semicolonToken);
}
// End of compilation unit
// Types
public TypeTree newType(TypeTree basicOrClassType,
Optional>, Tuple>>> dims) {
if (!dims.isPresent()) {
return basicOrClassType;
} else {
TypeTree result = basicOrClassType;
for (Tuple>, Tuple> dim : dims.get()) {
result = newArrayTypeTreeWithAnnotations(result, dim);
}
return result;
}
}
public TypeArgumentListTreeImpl newTypeArgumentList(InternalSyntaxToken openBracketToken,
Tree typeArgument, Optional>> rests, InternalSyntaxToken closeBracketToken) {
ImmutableList.Builder typeArguments = ImmutableList.builder();
ImmutableList.Builder separators = ImmutableList.builder();
typeArguments.add(typeArgument);
if (rests.isPresent()) {
for (Tuple rest : rests.get()) {
separators.add(rest.first());
typeArguments.add(rest.second());
}
}
return new TypeArgumentListTreeImpl(openBracketToken, typeArguments.build(), separators.build(), closeBracketToken);
}
public TypeArgumentListTreeImpl newDiamondTypeArgument(InternalSyntaxToken openBracketToken, InternalSyntaxToken closeBracketToken) {
return new TypeArgumentListTreeImpl(openBracketToken, ImmutableList.of(), ImmutableList.of(), closeBracketToken);
}
public Tree completeTypeArgument(Optional> annotations, Tree partial) {
if (partial.is(Tree.Kind.UNBOUNDED_WILDCARD, Tree.Kind.EXTENDS_WILDCARD, Tree.Kind.SUPER_WILDCARD)) {
List annotationList = annotations.isPresent() ?
ImmutableList.builder().addAll(annotations.get()).build() :
ImmutableList.of();
((WildcardTreeImpl) partial).complete(annotationList);
} else {
completeTypeTreeWithAnnotations((TypeTree) partial, annotations);
}
return partial;
}
public TypeTree newBasicTypeArgument(TypeTree type) {
return type;
}
public WildcardTreeImpl completeWildcardTypeArgument(InternalSyntaxToken queryToken, Optional partial) {
return partial.isPresent() ?
partial.get().complete(queryToken) :
new WildcardTreeImpl(queryToken);
}
public WildcardTreeImpl newWildcardTypeArguments(InternalSyntaxToken extendsOrSuperToken, Optional> annotations, TypeTree type) {
completeTypeTreeWithAnnotations(type, annotations);
return new WildcardTreeImpl(
JavaKeyword.EXTENDS.getValue().equals(extendsOrSuperToken.text()) ? Kind.EXTENDS_WILDCARD : Kind.SUPER_WILDCARD,
extendsOrSuperToken,
type);
}
public TypeParameterListTreeImpl newTypeParameterList(InternalSyntaxToken openBracketToken, TypeParameterTreeImpl typeParameter, Optional>> rests, InternalSyntaxToken closeBracketToken) {
ImmutableList.Builder typeParameters = ImmutableList.builder();
typeParameters.add(typeParameter);
ImmutableList.Builder separators = ImmutableList.builder();
if (rests.isPresent()) {
for (Tuple rest : rests.get()) {
separators.add(rest.first());
typeParameters.add(rest.second());
}
}
return new TypeParameterListTreeImpl(openBracketToken, typeParameters.build(), separators.build(), closeBracketToken);
}
public TypeParameterTreeImpl completeTypeParameter(Optional> annotations, InternalSyntaxToken identifierToken, Optional partial) {
IdentifierTreeImpl identifier = new IdentifierTreeImpl(identifierToken);
completeTypeTreeWithAnnotations(identifier, annotations);
return partial.isPresent() ?
partial.get().complete(identifier) :
new TypeParameterTreeImpl(identifier);
}
public TypeParameterTreeImpl newTypeParameter(InternalSyntaxToken extendsToken, BoundListTreeImpl bounds) {
return new TypeParameterTreeImpl(extendsToken, bounds);
}
public BoundListTreeImpl newBounds(TypeTree classType, Optional>> rests) {
ImmutableList.Builder classTypes = ImmutableList.builder();
ImmutableList.Builder separators = ImmutableList.builder();
classTypes.add(classType);
if (rests.isPresent()) {
for (Tuple rest : rests.get()) {
separators.add(rest.first());
classTypes.add(rest.second());
}
}
return new BoundListTreeImpl(classTypes.build(), separators.build());
}
// End of types
// Classes, enums and interfaces
public ClassTreeImpl completeClassDeclaration(
InternalSyntaxToken classSyntaxToken,
InternalSyntaxToken identifierToken, Optional typeParameters,
Optional> extendsClause,
Optional> implementsClause,
ClassTreeImpl partial) {
IdentifierTreeImpl identifier = new IdentifierTreeImpl(identifierToken);
partial.completeDeclarationKeyword(classSyntaxToken);
partial.completeIdentifier(identifier);
if (typeParameters.isPresent()) {
partial.completeTypeParameters(typeParameters.get());
}
if (extendsClause.isPresent()) {
partial.completeSuperclass(extendsClause.get().first(), extendsClause.get().second());
}
if (implementsClause.isPresent()) {
InternalSyntaxToken implementsKeyword = implementsClause.get().first();
QualifiedIdentifierListTreeImpl interfaces = implementsClause.get().second();
partial.completeInterfaces(implementsKeyword, interfaces);
}
return partial;
}
private static ClassTreeImpl newClassBody(Kind kind, InternalSyntaxToken openBraceSyntaxToken,
Optional> members, InternalSyntaxToken closeBraceTokenSyntaxToken) {
ImmutableList.Builder builder = ImmutableList.builder();
if (members.isPresent()) {
for (JavaTree member : members.get()) {
if (member instanceof VariableDeclaratorListTreeImpl) {
for (VariableTreeImpl variable : (VariableDeclaratorListTreeImpl) member) {
builder.add(variable);
}
} else {
builder.add(member);
}
}
}
return new ClassTreeImpl(kind, openBraceSyntaxToken, builder.build(), closeBraceTokenSyntaxToken);
}
public ClassTreeImpl newClassBody(InternalSyntaxToken openBraceToken, Optional> members, InternalSyntaxToken closeBraceToken) {
return newClassBody(Kind.CLASS, openBraceToken, members, closeBraceToken);
}
public ClassTreeImpl newEnumDeclaration(
InternalSyntaxToken enumToken,
InternalSyntaxToken identifierToken,
Optional> implementsClause,
InternalSyntaxToken openBraceToken,
Optional> enumConstants,
Optional semicolonToken,
Optional> enumDeclarations,
InternalSyntaxToken closeBraceToken) {
List members = Lists.newLinkedList();
EnumConstantTreeImpl lastEnumConstant = null;
if (enumConstants.isPresent()) {
for (EnumConstantTreeImpl enumConstant : enumConstants.get()) {
members.add(enumConstant);
lastEnumConstant = enumConstant;
}
}
if (semicolonToken.isPresent()) {
InternalSyntaxToken semicolon = semicolonToken.get();
// add the semicolon as endToken of the last enumConstant, or as empty statement in the enum members
if (lastEnumConstant != null) {
lastEnumConstant.setEndToken(semicolon);
} else {
members.add(newEmptyMember(semicolon));
}
}
if (enumDeclarations.isPresent()) {
for (JavaTree enumDeclaration : enumDeclarations.get()) {
members.add(enumDeclaration);
}
}
ClassTreeImpl result = newClassBody(Kind.ENUM, openBraceToken, Optional.of((List) ImmutableList.builder().addAll(members).build()), closeBraceToken);
result.completeDeclarationKeyword(enumToken);
IdentifierTreeImpl identifier = new IdentifierTreeImpl(identifierToken);
result.completeIdentifier(identifier);
if (implementsClause.isPresent()) {
InternalSyntaxToken implementsKeyword = implementsClause.get().first();
QualifiedIdentifierListTreeImpl interfaces = implementsClause.get().second();
result.completeInterfaces(implementsKeyword, interfaces);
}
return result;
}
public EnumConstantTreeImpl newEnumConstant(
Optional> annotations, InternalSyntaxToken identifierToken,
Optional arguments,
Optional classBody,
Optional commaToken) {
IdentifierTreeImpl identifier = new IdentifierTreeImpl(identifierToken);
ArgumentListTreeImpl defaultArguments = new ArgumentListTreeImpl(ImmutableList.of(), ImmutableList.of());
NewClassTreeImpl newClass = new NewClassTreeImpl(arguments.or(defaultArguments), classBody.orNull());
newClass.completeWithIdentifier(identifier);
return new EnumConstantTreeImpl(modifiers((Optional>) (Optional>) annotations), identifier, newClass, commaToken.orNull());
}
public ClassTreeImpl completeInterfaceDeclaration(
InternalSyntaxToken interfaceToken,
InternalSyntaxToken identifierToken, Optional typeParameters,
Optional> extendsClause,
ClassTreeImpl partial) {
IdentifierTreeImpl identifier = new IdentifierTreeImpl(identifierToken);
partial.completeDeclarationKeyword(interfaceToken);
partial.completeIdentifier(identifier);
if (typeParameters.isPresent()) {
partial.completeTypeParameters(typeParameters.get());
}
if (extendsClause.isPresent()) {
InternalSyntaxToken extendsKeyword = extendsClause.get().first();
QualifiedIdentifierListTreeImpl interfaces = extendsClause.get().second();
partial.completeInterfaces(extendsKeyword, interfaces);
}
return partial;
}
public ClassTreeImpl newInterfaceBody(InternalSyntaxToken openBraceToken, Optional> members, InternalSyntaxToken closeBraceToken) {
return newClassBody(Kind.INTERFACE, openBraceToken, members, closeBraceToken);
}
// TODO Create an intermediate implementation interface for completing modifiers
public JavaTree completeMember(ModifiersTreeImpl modifiers, JavaTree partial) {
if (partial instanceof ClassTreeImpl) {
((ClassTreeImpl) partial).completeModifiers(modifiers);
} else if (partial instanceof VariableDeclaratorListTreeImpl) {
for (VariableTreeImpl variable : (VariableDeclaratorListTreeImpl) partial) {
variable.completeModifiers(modifiers);
}
} else if (partial instanceof MethodTreeImpl) {
((MethodTreeImpl) partial).completeWithModifiers(modifiers);
} else {
throw new IllegalArgumentException();
}
return partial;
}
public BlockTreeImpl newInitializerMember(Optional staticToken, BlockTreeImpl block) {
if (staticToken.isPresent()) {
return new StaticInitializerTreeImpl(staticToken.get(), (InternalSyntaxToken) block.openBraceToken(), block.body(),
(InternalSyntaxToken) block.closeBraceToken());
} else {
return new BlockTreeImpl(Kind.INITIALIZER, (InternalSyntaxToken) block.openBraceToken(), block.body(), (InternalSyntaxToken) block.closeBraceToken());
}
}
public EmptyStatementTreeImpl newEmptyMember(InternalSyntaxToken semicolonToken) {
return new EmptyStatementTreeImpl(semicolonToken);
}
public MethodTreeImpl completeGenericMethodOrConstructorDeclaration(TypeParameterListTreeImpl typeParameters, MethodTreeImpl partial) {
return partial.completeWithTypeParameters(typeParameters);
}
private MethodTreeImpl newMethodOrConstructor(
Optional type, InternalSyntaxToken identifierToken, FormalParametersListTreeImpl parameters,
Optional>, Tuple>>> annotatedDimensions,
Optional> throwsClause,
JavaTree blockOrSemicolon) {
IdentifierTreeImpl identifier = new IdentifierTreeImpl(identifierToken);
ArrayTypeTreeImpl nestedDimensions = newArrayTypeTreeWithAnnotations(annotatedDimensions);
TypeTree actualType;
if (type.isPresent()) {
actualType = applyDim(type.get(), nestedDimensions);
} else {
actualType = null;
}
BlockTreeImpl block = null;
InternalSyntaxToken semicolonToken = null;
if (blockOrSemicolon.is(Tree.Kind.BLOCK)) {
block = (BlockTreeImpl) blockOrSemicolon;
} else {
semicolonToken = (InternalSyntaxToken) blockOrSemicolon;
}
InternalSyntaxToken throwsToken = null;
ListTree throwsClauses = QualifiedIdentifierListTreeImpl.emptyList();
if (throwsClause.isPresent()) {
throwsToken = throwsClause.get().first();
throwsClauses = throwsClause.get().second();
}
return new MethodTreeImpl(
actualType,
identifier,
parameters,
throwsToken,
throwsClauses,
block,
semicolonToken);
}
public MethodTreeImpl newMethod(
TypeTree type, InternalSyntaxToken identifierToken, FormalParametersListTreeImpl parameters,
Optional>, Tuple>>> annotatedDimensions,
Optional> throwsClause,
JavaTree blockOrSemicolon) {
return newMethodOrConstructor(Optional.of(type), identifierToken, parameters, annotatedDimensions, throwsClause, blockOrSemicolon);
}
public MethodTreeImpl newConstructor(
InternalSyntaxToken identifierToken, FormalParametersListTreeImpl parameters,
Optional>, Tuple>>> annotatedDimensions,
Optional> throwsClause,
JavaTree blockOrSemicolon) {
return newMethodOrConstructor(Optional.absent(), identifierToken, parameters, annotatedDimensions, throwsClause, blockOrSemicolon);
}
public VariableDeclaratorListTreeImpl completeFieldDeclaration(TypeTree type, VariableDeclaratorListTreeImpl partial, InternalSyntaxToken semicolonToken) {
for (VariableTreeImpl variable : partial) {
variable.completeType(type);
}
// store the semicolon as endToken for the last variable
partial.get(partial.size() - 1).setEndToken(semicolonToken);
return partial;
}
// End of classes, enums and interfaces
// Annotations
public ClassTreeImpl completeAnnotationType(InternalSyntaxToken atToken, InternalSyntaxToken interfaceToken, InternalSyntaxToken identifier, ClassTreeImpl partial) {
return partial.complete(
atToken,
interfaceToken,
new IdentifierTreeImpl(identifier));
}
public ClassTreeImpl newAnnotationType(InternalSyntaxToken openBraceToken, Optional> annotationTypeElementDeclarations, InternalSyntaxToken closeBraceToken) {
// TODO
ModifiersTreeImpl emptyModifiers = ModifiersTreeImpl.emptyModifiers();
ImmutableList.Builder members = ImmutableList.builder();
if (annotationTypeElementDeclarations.isPresent()) {
for (JavaTree annotationTypeElementDeclaration : annotationTypeElementDeclarations.get()) {
if (annotationTypeElementDeclaration.getGrammarRuleKey().equals(JavaLexer.VARIABLE_DECLARATORS)) {
for (VariableTreeImpl variable : (VariableDeclaratorListTreeImpl) annotationTypeElementDeclaration) {
members.add(variable);
}
} else if (!annotationTypeElementDeclaration.is(Kind.TOKEN)) {
members.add(annotationTypeElementDeclaration);
}
}
}
return new ClassTreeImpl(emptyModifiers, openBraceToken, members.build(), closeBraceToken);
}
public JavaTree completeAnnotationTypeMember(ModifiersTreeImpl modifiers, JavaTree partial) {
if (partial.getGrammarRuleKey().equals(JavaLexer.VARIABLE_DECLARATORS)) {
for (VariableTreeImpl variable : (VariableDeclaratorListTreeImpl) partial) {
variable.completeModifiers(modifiers);
}
} else if (partial.is(Kind.CLASS, Kind.INTERFACE, Kind.ENUM, Kind.ANNOTATION_TYPE)) {
((ClassTreeImpl) partial).completeModifiers(modifiers);
} else if (partial.is(Kind.METHOD)) {
((MethodTreeImpl) partial).completeWithModifiers(modifiers);
} else {
throw new IllegalArgumentException("Unsupported type: " + partial);
}
return partial;
}
public MethodTreeImpl completeAnnotationMethod(TypeTree type, InternalSyntaxToken identifierToken, MethodTreeImpl partial, InternalSyntaxToken semiToken) {
partial.complete(type, new IdentifierTreeImpl(identifierToken), semiToken);
return partial;
}
public MethodTreeImpl newAnnotationTypeMethod(InternalSyntaxToken openParenToken, InternalSyntaxToken closeParenToken,
Optional> defaultValue) {
FormalParametersListTreeImpl parameters = new FormalParametersListTreeImpl(openParenToken, closeParenToken);
InternalSyntaxToken defaultToken = null;
ExpressionTree defaultExpression = null;
if (defaultValue.isPresent()) {
defaultToken = defaultValue.get().first();
defaultExpression = defaultValue.get().second();
}
return new MethodTreeImpl(parameters, defaultToken, defaultExpression);
}
public Tuple newDefaultValue(InternalSyntaxToken defaultToken, ExpressionTree elementValue) {
return new Tuple<>(defaultToken, elementValue);
}
public AnnotationTreeImpl newAnnotation(InternalSyntaxToken atToken, TypeTree qualifiedIdentifier, Optional arguments) {
ArgumentListTreeImpl defaultValue = new ArgumentListTreeImpl(ImmutableList.of(), ImmutableList.of());
return new AnnotationTreeImpl(atToken, qualifiedIdentifier, arguments.or(defaultValue));
}
public ArgumentListTreeImpl completeNormalAnnotation(InternalSyntaxToken openParenToken, Optional partial, InternalSyntaxToken closeParenToken) {
if (!partial.isPresent()) {
return new ArgumentListTreeImpl(openParenToken, closeParenToken);
}
ArgumentListTreeImpl elementValuePairs = partial.get();
elementValuePairs.complete(openParenToken, closeParenToken);
return elementValuePairs;
}
public ArgumentListTreeImpl newNormalAnnotation(AssignmentExpressionTreeImpl elementValuePair, Optional>> rests) {
ImmutableList.Builder expressions = ImmutableList.builder();
expressions.add(elementValuePair);
ImmutableList.Builder separators = ImmutableList.builder();
if (rests.isPresent()) {
for (Tuple rest : rests.get()) {
separators.add(rest.first());
expressions.add(rest.second());
}
}
return new ArgumentListTreeImpl(expressions.build(), separators.build());
}
public AssignmentExpressionTreeImpl newElementValuePair(InternalSyntaxToken identifierToken, InternalSyntaxToken operator, ExpressionTree elementValue) {
return new AssignmentExpressionTreeImpl(
kindMaps.getAssignmentOperator((JavaPunctuator) operator.getGrammarRuleKey()),
new IdentifierTreeImpl(identifierToken),
operator,
elementValue);
}
public NewArrayTreeImpl completeElementValueArrayInitializer(
InternalSyntaxToken openBraceToken, Optional partial, InternalSyntaxToken closeBraceToken) {
NewArrayTreeImpl elementValues = partial.or(new NewArrayTreeImpl(ImmutableList.of(), InitializerListTreeImpl.emptyList()));
return elementValues.completeWithCurlyBraces(openBraceToken, closeBraceToken);
}
public NewArrayTreeImpl newElementValueArrayInitializer(List>> rests) {
ImmutableList.Builder expressions = ImmutableList.builder();
ImmutableList.Builder separators = ImmutableList.builder();
for (Tuple> tuple : rests) {
expressions.add(tuple.first());
if (tuple.second().isPresent()) {
separators.add(tuple.second().get());
}
}
return new NewArrayTreeImpl(ImmutableList.of(), new InitializerListTreeImpl(expressions.build(), separators.build()));
}
public ArgumentListTreeImpl newSingleElementAnnotation(InternalSyntaxToken openParenToken, ExpressionTree elementValue, InternalSyntaxToken closeParenToken) {
return new ArgumentListTreeImpl(openParenToken, elementValue, closeParenToken);
}
// End of annotations
// Formal parameters
public FormalParametersListTreeImpl completeParenFormalParameters(InternalSyntaxToken openParenToken, Optional partial,
InternalSyntaxToken closeParenToken) {
return partial.isPresent() ?
partial.get().complete(openParenToken, closeParenToken) :
new FormalParametersListTreeImpl(openParenToken, closeParenToken);
}
public FormalParametersListTreeImpl completeTypeFormalParameters(ModifiersTreeImpl modifiers, TypeTree type, FormalParametersListTreeImpl partial) {
VariableTreeImpl variable = partial.get(0);
variable.completeModifiersAndType(modifiers, type);
return partial;
}
public FormalParametersListTreeImpl prependNewFormalParameter(VariableTreeImpl variable, Optional> rest) {
if (rest.isPresent()) {
InternalSyntaxToken comma = rest.get().first();
FormalParametersListTreeImpl partial = rest.get().second();
partial.add(0, variable);
// store the comma as endToken for the variable
variable.setEndToken(comma);
return partial;
} else {
return new FormalParametersListTreeImpl(variable);
}
}
public FormalParametersListTreeImpl newVariableArgumentFormalParameter(Optional> annotations,
InternalSyntaxToken ellipsisToken, VariableTreeImpl variable) {
variable.addEllipsisDimension(new ArrayTypeTreeImpl(null, annotations.or(ImmutableList.of()), ellipsisToken));
return new FormalParametersListTreeImpl(
annotations.or(ImmutableList.of()),
ellipsisToken,
variable);
}
public VariableTreeImpl newVariableDeclaratorId(InternalSyntaxToken identifierToken,
Optional>, Tuple>>> dims) {
IdentifierTreeImpl identifier = new IdentifierTreeImpl(identifierToken);
ArrayTypeTreeImpl nestedDimensions = newArrayTypeTreeWithAnnotations(dims);
return new VariableTreeImpl(identifier, nestedDimensions);
}
public VariableTreeImpl newFormalParameter(ModifiersTreeImpl modifiers, TypeTree type, VariableTreeImpl variable) {
return variable.completeType(type);
}
// End of formal parameters
// Statements
public VariableDeclaratorListTreeImpl completeLocalVariableDeclaration(
ModifiersTreeImpl modifiers,
TypeTree type,
VariableDeclaratorListTreeImpl variables,
InternalSyntaxToken semicolonSyntaxToken) {
for (VariableTreeImpl variable : variables) {
variable.completeModifiersAndType(modifiers, type);
}
// store the semicolon as endToken for the last variable
variables.get(variables.size() - 1).setEndToken(semicolonSyntaxToken);
return variables;
}
public VariableDeclaratorListTreeImpl newVariableDeclarators(VariableTreeImpl variable, Optional>> rests) {
ImmutableList.Builder variables = ImmutableList.builder();
variables.add(variable);
if (rests.isPresent()) {
VariableTreeImpl previousVariable = variable;
for (Tuple rest : rests.get()) {
VariableTreeImpl newVariable = rest.second();
InternalSyntaxToken separator = rest.first();
variables.add(newVariable);
// store the separator
previousVariable.setEndToken(separator);
previousVariable = newVariable;
}
}
return new VariableDeclaratorListTreeImpl(variables.build());
}
public VariableTreeImpl completeVariableDeclarator(InternalSyntaxToken identifierToken,
Optional>, Tuple>>> dimensions,
Optional partial) {
IdentifierTreeImpl identifier = new IdentifierTreeImpl(identifierToken);
ArrayTypeTreeImpl nestedDimensions = newArrayTypeTreeWithAnnotations(dimensions);
if (partial.isPresent()) {
return partial.get().completeIdentifierAndDims(identifier, nestedDimensions);
} else {
return new VariableTreeImpl(identifier, nestedDimensions);
}
}
public VariableTreeImpl newVariableDeclarator(InternalSyntaxToken equalToken, ExpressionTree initializer) {
return new VariableTreeImpl(equalToken, initializer);
}
public BlockTreeImpl block(InternalSyntaxToken openBraceToken, BlockStatementListTreeImpl blockStatements, InternalSyntaxToken closeBraceToken) {
return new BlockTreeImpl(openBraceToken, blockStatements, closeBraceToken);
}
public AssertStatementTreeImpl completeAssertStatement(
InternalSyntaxToken assertToken, ExpressionTree expression, Optional detailExpression, InternalSyntaxToken semicolonSyntaxToken) {
return detailExpression.isPresent() ?
detailExpression.get().complete(assertToken, expression, semicolonSyntaxToken) :
new AssertStatementTreeImpl(assertToken, expression, semicolonSyntaxToken);
}
public AssertStatementTreeImpl newAssertStatement(InternalSyntaxToken colonToken, ExpressionTree expression) {
return new AssertStatementTreeImpl(colonToken, expression);
}
public IfStatementTreeImpl completeIf(InternalSyntaxToken ifToken, InternalSyntaxToken openParenToken, ExpressionTree condition, InternalSyntaxToken closeParenToken,
StatementTree statement,
Optional elseClause) {
if (elseClause.isPresent()) {
return elseClause.get().complete(ifToken, openParenToken, condition, closeParenToken, statement);
} else {
return new IfStatementTreeImpl(ifToken, openParenToken, condition, closeParenToken, statement);
}
}
public IfStatementTreeImpl newIfWithElse(InternalSyntaxToken elseToken, StatementTree elseStatement) {
return new IfStatementTreeImpl(elseToken, elseStatement);
}
public ForStatementTreeImpl newStandardForStatement(
InternalSyntaxToken forTokenKeyword,
InternalSyntaxToken openParenToken,
Optional forInit, InternalSyntaxToken forInitSemicolonToken,
Optional expression, InternalSyntaxToken expressionSemicolonToken,
Optional forUpdate, InternalSyntaxToken closeParenToken,
StatementTree statement) {
StatementExpressionListTreeImpl forInitStatement = forInit.or(new StatementExpressionListTreeImpl(ImmutableList.of(), ImmutableList.of()));
StatementExpressionListTreeImpl forUpdateStatement = forUpdate.or(new StatementExpressionListTreeImpl(ImmutableList.of(), ImmutableList.of()));
return new ForStatementTreeImpl(
forTokenKeyword,
openParenToken,
forInitStatement,
forInitSemicolonToken,
expression.orNull(),
expressionSemicolonToken,
forUpdateStatement,
closeParenToken,
statement);
}
public StatementExpressionListTreeImpl newForInitDeclaration(ModifiersTreeImpl modifiers, TypeTree type, VariableDeclaratorListTreeImpl variables) {
for (VariableTreeImpl variable : variables) {
variable.completeModifiersAndType(modifiers, type);
}
return new StatementExpressionListTreeImpl(variables, ImmutableList.of());
}
public StatementExpressionListTreeImpl newStatementExpressions(ExpressionTree expression, Optional>> rests) {
ImmutableList.Builder statements = ImmutableList.builder();
statements.add(new ExpressionStatementTreeImpl(expression, null));
ImmutableList.Builder separators = ImmutableList.builder();
if (rests.isPresent()) {
for (Tuple rest : rests.get()) {
separators.add(rest.first());
statements.add(new ExpressionStatementTreeImpl(rest.second(), null));
}
}
return new StatementExpressionListTreeImpl(statements.build(), separators.build());
}
public ForEachStatementImpl newForeachStatement(
InternalSyntaxToken forKeyword,
InternalSyntaxToken openParenToken,
VariableTreeImpl variable, InternalSyntaxToken colonToken, ExpressionTree expression,
InternalSyntaxToken closeParenToken,
StatementTree statement) {
return new ForEachStatementImpl(forKeyword, openParenToken, variable, colonToken, expression, closeParenToken, statement);
}
public WhileStatementTreeImpl whileStatement(InternalSyntaxToken whileToken, InternalSyntaxToken openParen, ExpressionTree expression, InternalSyntaxToken closeParen,
StatementTree statement) {
return new WhileStatementTreeImpl(whileToken, openParen, expression, closeParen, statement);
}
public DoWhileStatementTreeImpl doWhileStatement(InternalSyntaxToken doToken, StatementTree statement,
InternalSyntaxToken whileToken, InternalSyntaxToken openParen, ExpressionTree expression,
InternalSyntaxToken closeParen, InternalSyntaxToken semicolon) {
return new DoWhileStatementTreeImpl(doToken, statement, whileToken, openParen, expression, closeParen, semicolon);
}
public TryStatementTreeImpl completeStandardTryStatement(InternalSyntaxToken tryToken, BlockTreeImpl block, TryStatementTreeImpl partial) {
return partial.completeStandardTry(tryToken, block);
}
public TryStatementTreeImpl newTryCatch(Optional> catches, Optional finallyBlock) {
List catchTrees = catches.or(ImmutableList.of());
if (finallyBlock.isPresent()) {
return finallyBlock.get().completeWithCatches(catchTrees);
} else {
return new TryStatementTreeImpl(catchTrees, null, null);
}
}
public CatchTreeImpl newCatchClause(InternalSyntaxToken catchToken, InternalSyntaxToken openParenToken, VariableTreeImpl parameter,
InternalSyntaxToken closeParenToken, BlockTreeImpl block) {
return new CatchTreeImpl(catchToken, openParenToken, parameter, closeParenToken, block);
}
public VariableTreeImpl newCatchFormalParameter(ModifiersTreeImpl modifiers, TypeTree type, VariableTreeImpl parameter) {
if (!modifiers.isEmpty()) {
parameter.completeModifiers(modifiers);
}
return parameter.completeType(type);
}
public TypeTree newCatchType(TypeTree qualifiedIdentifier, Optional>> rests) {
if (!rests.isPresent()) {
return qualifiedIdentifier;
}
ImmutableList.Builder types = ImmutableList.builder();
types.add(qualifiedIdentifier);
ImmutableList.Builder separators = ImmutableList.builder();
for (Tuple rest : rests.get()) {
separators.add(rest.first());
types.add(rest.second());
}
return new UnionTypeTreeImpl(new TypeUnionListTreeImpl(types.build(), separators.build()));
}
public TryStatementTreeImpl newFinallyBlock(InternalSyntaxToken finallyToken, BlockTreeImpl block) {
return new TryStatementTreeImpl(finallyToken, block);
}
public TryStatementTreeImpl newTryWithResourcesStatement(
InternalSyntaxToken tryToken, InternalSyntaxToken openParenToken, ResourceListTreeImpl resources, InternalSyntaxToken closeParenToken,
BlockTreeImpl block,
Optional> catches, Optional finallyBlock) {
List catchTrees = catches.or(ImmutableList.of());
if (finallyBlock.isPresent()) {
return finallyBlock.get().completeTryWithResources(tryToken, openParenToken, resources, closeParenToken, block, catchTrees);
} else {
return new TryStatementTreeImpl(tryToken, openParenToken, resources, closeParenToken, block, catchTrees);
}
}
public ResourceListTreeImpl newResources(List>> rests) {
ImmutableList.Builder resources = ImmutableList.builder();
ImmutableList.Builder separators = ImmutableList.builder();
for (Tuple> rest : rests) {
if (rest.second().isPresent()) {
separators.add(rest.second().get());
}
resources.add(rest.first());
}
return new ResourceListTreeImpl(resources.build(), separators.build());
}
public VariableTreeImpl newResource(ModifiersTreeImpl modifiers, TypeTree classType, VariableTreeImpl partial, InternalSyntaxToken equalToken, ExpressionTree expression) {
if (!modifiers.isEmpty()) {
partial.completeModifiers(modifiers);
}
return partial.completeTypeAndInitializer(classType, equalToken, expression);
}
public SwitchStatementTreeImpl switchStatement(InternalSyntaxToken switchToken, InternalSyntaxToken openParenToken, ExpressionTree expression,
InternalSyntaxToken closeParenToken,
InternalSyntaxToken openBraceToken, Optional> optionalGroups, InternalSyntaxToken closeBraceToken) {
List groups = optionalGroups.or(Collections.emptyList());
return new SwitchStatementTreeImpl(switchToken, openParenToken, expression, closeParenToken,
openBraceToken, groups, closeBraceToken);
}
public CaseGroupTreeImpl switchGroup(List labels, BlockStatementListTreeImpl blockStatements) {
return new CaseGroupTreeImpl(labels, blockStatements);
}
public CaseLabelTreeImpl newCaseSwitchLabel(InternalSyntaxToken caseSyntaxToken, ExpressionTree expression, InternalSyntaxToken colonSyntaxToken) {
return new CaseLabelTreeImpl(caseSyntaxToken, expression, colonSyntaxToken);
}
public CaseLabelTreeImpl newDefaultSwitchLabel(InternalSyntaxToken defaultToken, InternalSyntaxToken colonToken) {
return new CaseLabelTreeImpl(defaultToken, null, colonToken);
}
public SynchronizedStatementTreeImpl synchronizedStatement(InternalSyntaxToken synchronizedToken, InternalSyntaxToken openParenToken, ExpressionTree expression,
InternalSyntaxToken closeParenToken, BlockTreeImpl block) {
return new SynchronizedStatementTreeImpl(synchronizedToken, openParenToken, expression, closeParenToken, block);
}
public BreakStatementTreeImpl breakStatement(InternalSyntaxToken breakToken, Optional identifierToken, InternalSyntaxToken semicolonSyntaxToken) {
IdentifierTreeImpl identifier = null;
if (identifierToken.isPresent()) {
identifier = new IdentifierTreeImpl(identifierToken.get());
}
return new BreakStatementTreeImpl(breakToken, identifier, semicolonSyntaxToken);
}
public ContinueStatementTreeImpl continueStatement(InternalSyntaxToken continueToken, Optional identifierToken, InternalSyntaxToken semicolonToken) {
IdentifierTreeImpl identifier = null;
if (identifierToken.isPresent()) {
identifier = new IdentifierTreeImpl(identifierToken.get());
}
return new ContinueStatementTreeImpl(continueToken, identifier, semicolonToken);
}
public ReturnStatementTreeImpl returnStatement(InternalSyntaxToken returnToken, Optional expression, InternalSyntaxToken semicolonSyntaxToken) {
return new ReturnStatementTreeImpl(returnToken, expression.orNull(), semicolonSyntaxToken);
}
public ThrowStatementTreeImpl throwStatement(InternalSyntaxToken throwToken, ExpressionTree expression, InternalSyntaxToken semicolonToken) {
return new ThrowStatementTreeImpl(throwToken, expression, semicolonToken);
}
public LabeledStatementTreeImpl labeledStatement(InternalSyntaxToken identifierToken, InternalSyntaxToken colon, StatementTree statement) {
IdentifierTreeImpl identifier = new IdentifierTreeImpl(identifierToken);
return new LabeledStatementTreeImpl(identifier, colon, statement);
}
public ExpressionStatementTreeImpl expressionStatement(ExpressionTree expression, InternalSyntaxToken semicolonToken) {
return new ExpressionStatementTreeImpl(expression, semicolonToken);
}
public EmptyStatementTreeImpl emptyStatement(InternalSyntaxToken semicolon) {
return new EmptyStatementTreeImpl(semicolon);
}
public BlockStatementListTreeImpl blockStatements(Optional> blockStatements) {
ImmutableList.Builder builder = ImmutableList.builder();
if (blockStatements.isPresent()) {
for (BlockStatementListTreeImpl blockStatement : blockStatements.get()) {
builder.addAll(blockStatement);
}
}
return new BlockStatementListTreeImpl(builder.build());
}
public BlockStatementListTreeImpl wrapInBlockStatements(VariableDeclaratorListTreeImpl variables) {
return new BlockStatementListTreeImpl(variables);
}
public BlockStatementListTreeImpl newInnerClassOrEnum(ModifiersTreeImpl modifiers, ClassTreeImpl classTree) {
classTree.completeModifiers(modifiers);
return new BlockStatementListTreeImpl(ImmutableList.of(classTree));
}
public BlockStatementListTreeImpl wrapInBlockStatements(StatementTree statement) {
return new BlockStatementListTreeImpl(ImmutableList.of(statement));
}
// End of statements
// Expressions
public ExpressionTree assignmentExpression(ExpressionTree expression, Optional> operatorAndOperands) {
if (!operatorAndOperands.isPresent()) {
return expression;
}
ExpressionTree result = null;
InternalSyntaxToken lastOperator = null;
for (OperatorAndOperand operatorAndOperand : Lists.reverse(operatorAndOperands.get())) {
if (lastOperator == null) {
result = operatorAndOperand.operand();
} else {
result = new AssignmentExpressionTreeImpl(
kindMaps.getAssignmentOperator((JavaPunctuator) lastOperator.getGrammarRuleKey()),
operatorAndOperand.operand(),
lastOperator,
result);
}
lastOperator = operatorAndOperand.operator();
}
result = new AssignmentExpressionTreeImpl(
kindMaps.getAssignmentOperator((JavaPunctuator) lastOperator.getGrammarRuleKey()),
expression,
lastOperator,
result);
return result;
}
public ExpressionTree completeTernaryExpression(ExpressionTree expression, Optional partial) {
return partial.isPresent() ?
partial.get().complete(expression) :
expression;
}
public ConditionalExpressionTreeImpl newTernaryExpression(InternalSyntaxToken queryToken, ExpressionTree trueExpression, InternalSyntaxToken colonToken,
ExpressionTree falseExpression) {
return new ConditionalExpressionTreeImpl(queryToken, trueExpression, colonToken, falseExpression);
}
public ExpressionTree completeInstanceofExpression(ExpressionTree expression, Optional partial) {
return partial.isPresent() ?
partial.get().complete(expression) :
expression;
}
public InstanceOfTreeImpl newInstanceofExpression(InternalSyntaxToken instanceofToken, TypeTree type) {
return new InstanceOfTreeImpl(instanceofToken, type);
}
private static class OperatorAndOperand {
private final InternalSyntaxToken operator;
private final ExpressionTree operand;
public OperatorAndOperand(InternalSyntaxToken operator, ExpressionTree operand) {
this.operator = operator;
this.operand = operand;
}
public InternalSyntaxToken operator() {
return operator;
}
public ExpressionTree operand() {
return operand;
}
}
private ExpressionTree binaryExpression(ExpressionTree expression, Optional> operatorAndOperands) {
if (!operatorAndOperands.isPresent()) {
return expression;
}
ExpressionTree result = expression;
for (OperatorAndOperand operatorAndOperand : operatorAndOperands.get()) {
result = new BinaryExpressionTreeImpl(
kindMaps.getBinaryOperator((JavaPunctuator) operatorAndOperand.operator().getGrammarRuleKey()),
result,
operatorAndOperand.operator(),
operatorAndOperand.operand());
}
return result;
}
private OperatorAndOperand newOperatorAndOperand(InternalSyntaxToken operator, ExpressionTree operand) {
return new OperatorAndOperand(operator, operand);
}
// TODO Allow to use the same method several times
public OperatorAndOperand newOperatorAndOperand11(InternalSyntaxToken operator, ExpressionTree operand) {
return newOperatorAndOperand(operator, operand);
}
public ExpressionTree binaryExpression10(ExpressionTree expression, Optional> operatorAndOperands) {
return binaryExpression(expression, operatorAndOperands);
}
public OperatorAndOperand newOperatorAndOperand10(InternalSyntaxToken operator, ExpressionTree operand) {
return newOperatorAndOperand(operator, operand);
}
public ExpressionTree binaryExpression9(ExpressionTree expression, Optional> operatorAndOperands) {
return binaryExpression(expression, operatorAndOperands);
}
public OperatorAndOperand newOperatorAndOperand9(InternalSyntaxToken operator, ExpressionTree operand) {
return newOperatorAndOperand(operator, operand);
}
public ExpressionTree binaryExpression8(ExpressionTree expression, Optional> operatorAndOperands) {
return binaryExpression(expression, operatorAndOperands);
}
public OperatorAndOperand newOperatorAndOperand8(InternalSyntaxToken operator, ExpressionTree operand) {
return newOperatorAndOperand(operator, operand);
}
public ExpressionTree binaryExpression7(ExpressionTree expression, Optional> operatorAndOperands) {
return binaryExpression(expression, operatorAndOperands);
}
public OperatorAndOperand newOperatorAndOperand7(InternalSyntaxToken operator, ExpressionTree operand) {
return newOperatorAndOperand(operator, operand);
}
public ExpressionTree binaryExpression6(ExpressionTree expression, Optional> operatorAndOperands) {
return binaryExpression(expression, operatorAndOperands);
}
public OperatorAndOperand newOperatorAndOperand6(InternalSyntaxToken operator, ExpressionTree operand) {
return newOperatorAndOperand(operator, operand);
}
public ExpressionTree binaryExpression5(ExpressionTree expression, Optional> operatorAndOperands) {
return binaryExpression(expression, operatorAndOperands);
}
public OperatorAndOperand newOperatorAndOperand5(InternalSyntaxToken operator, ExpressionTree operand) {
return newOperatorAndOperand(operator, operand);
}
public ExpressionTree binaryExpression4(ExpressionTree expression, Optional> operatorAndOperands) {
return binaryExpression(expression, operatorAndOperands);
}
public OperatorAndOperand newOperatorAndOperand4(InternalSyntaxToken operator, ExpressionTree operand) {
return newOperatorAndOperand(operator, operand);
}
public ExpressionTree binaryExpression3(ExpressionTree expression, Optional> operatorAndOperands) {
return binaryExpression(expression, operatorAndOperands);
}
public OperatorAndOperand newOperatorAndOperand3(InternalSyntaxToken operator, ExpressionTree operand) {
return newOperatorAndOperand(operator, operand);
}
public ExpressionTree binaryExpression2(ExpressionTree expression, Optional> operatorAndOperands) {
return binaryExpression(expression, operatorAndOperands);
}
public OperatorAndOperand newOperatorAndOperand2(InternalSyntaxToken operator, ExpressionTree operand) {
return newOperatorAndOperand(operator, operand);
}
public ExpressionTree binaryExpression1(ExpressionTree expression, Optional> operatorAndOperands) {
return binaryExpression(expression, operatorAndOperands);
}
public OperatorAndOperand newOperatorAndOperand1(InternalSyntaxToken operator, ExpressionTree operand) {
return newOperatorAndOperand(operator, operand);
}
public ExpressionTree newPrefixedExpression(InternalSyntaxToken operatorToken, ExpressionTree expression) {
return new InternalPrefixUnaryExpression(kindMaps.getPrefixOperator((JavaPunctuator) operatorToken.getGrammarRuleKey()), operatorToken, expression);
}
public ExpressionTree newPostfixExpression(ExpressionTree expression, Optional postfixOperator) {
ExpressionTree result = expression;
if (postfixOperator.isPresent()) {
InternalSyntaxToken postfixOperatorToken = postfixOperator.get();
result = new InternalPostfixUnaryExpression(kindMaps.getPostfixOperator((JavaPunctuator) postfixOperator.get().getGrammarRuleKey()), result, postfixOperatorToken);
}
return result;
}
public ExpressionTree newTildaExpression(InternalSyntaxToken tildaToken, ExpressionTree expression) {
return new InternalPrefixUnaryExpression(Kind.BITWISE_COMPLEMENT, tildaToken, expression);
}
public ExpressionTree newBangExpression(InternalSyntaxToken bangToken, ExpressionTree expression) {
return new InternalPrefixUnaryExpression(Kind.LOGICAL_COMPLEMENT, bangToken, expression);
}
public ExpressionTree completeCastExpression(InternalSyntaxToken openParenToken, TypeCastExpressionTreeImpl partial) {
return partial.complete(openParenToken);
}
public TypeCastExpressionTreeImpl newBasicTypeCastExpression(PrimitiveTypeTreeImpl basicType, InternalSyntaxToken closeParenToken, ExpressionTree expression) {
return new TypeCastExpressionTreeImpl(basicType, closeParenToken, expression);
}
public TypeCastExpressionTreeImpl newClassCastExpression(TypeTree type, Optional> classTypes, InternalSyntaxToken closeParenToken,
ExpressionTree expression) {
BoundListTreeImpl bounds = BoundListTreeImpl.emptyList();
InternalSyntaxToken andToken = null;
if (classTypes.isPresent()) {
andToken = classTypes.get().first();
bounds = classTypes.get().second();
}
return new TypeCastExpressionTreeImpl(type, andToken, bounds, closeParenToken, expression);
}
public ExpressionTree completeMethodReference(MethodReferenceTreeImpl partial, Optional typeArguments, InternalSyntaxToken newOrIdentifierToken) {
TypeArguments typeArgs = null;
if (typeArguments.isPresent()) {
typeArgs = typeArguments.get();
}
partial.complete(typeArgs, new IdentifierTreeImpl(newOrIdentifierToken));
return partial;
}
public MethodReferenceTreeImpl newSuperMethodReference(InternalSyntaxToken superToken, InternalSyntaxToken doubleColonToken) {
IdentifierTree superIdentifier = new IdentifierTreeImpl(superToken);
return new MethodReferenceTreeImpl(superIdentifier, doubleColonToken);
}
public MethodReferenceTreeImpl newTypeMethodReference(Tree type, InternalSyntaxToken doubleColonToken) {
return new MethodReferenceTreeImpl(type, doubleColonToken);
}
public MethodReferenceTreeImpl newPrimaryMethodReference(ExpressionTree expression, InternalSyntaxToken doubleColonToken) {
return new MethodReferenceTreeImpl(expression, doubleColonToken);
}
public ExpressionTree lambdaExpression(LambdaParameterListTreeImpl parameters, InternalSyntaxToken arrowToken, Tree body) {
return new LambdaExpressionTreeImpl(
parameters.openParenToken(),
ImmutableList.builder().addAll(parameters).build(),
parameters.closeParenToken(),
arrowToken,
body);
}
public LambdaParameterListTreeImpl newInferedParameters(
InternalSyntaxToken openParenToken,
Optional>>>> identifiersOpt,
InternalSyntaxToken closeParenToken) {
ImmutableList.Builder params = ImmutableList.builder();
if (identifiersOpt.isPresent()) {
Tuple>>> identifiers = identifiersOpt.get();
VariableTreeImpl variable = identifiers.first();
params.add(variable);
VariableTreeImpl previousVariable = variable;
if (identifiers.second().isPresent()) {
for (Tuple identifier : identifiers.second().get()) {
variable = identifier.second();
params.add(variable);
InternalSyntaxToken comma = identifier.first();
previousVariable.setEndToken(comma);
previousVariable = variable;
}
}
}
return new LambdaParameterListTreeImpl(openParenToken, params.build(), closeParenToken);
}
public LambdaParameterListTreeImpl formalLambdaParameters(FormalParametersListTreeImpl formalParameters) {
return new LambdaParameterListTreeImpl(formalParameters.openParenToken(), formalParameters, formalParameters.closeParenToken());
}
public LambdaParameterListTreeImpl singleInferedParameter(VariableTreeImpl parameter) {
return new LambdaParameterListTreeImpl(null, ImmutableList.of(parameter), null);
}
public VariableTreeImpl newSimpleParameter(InternalSyntaxToken identifierToken) {
IdentifierTreeImpl identifier = new IdentifierTreeImpl(identifierToken);
return new VariableTreeImpl(identifier);
}
public ParenthesizedTreeImpl parenthesizedExpression(InternalSyntaxToken leftParenSyntaxToken, ExpressionTree expression, InternalSyntaxToken rightParenSyntaxToken) {
return new ParenthesizedTreeImpl(leftParenSyntaxToken, expression, rightParenSyntaxToken);
}
public ExpressionTree newExpression(InternalSyntaxToken newToken, Optional> annotations, ExpressionTree partial) {
TypeTree typeTree;
if (partial.is(Tree.Kind.NEW_CLASS)) {
NewClassTreeImpl newClassTree = (NewClassTreeImpl) partial;
newClassTree.completeWithNewKeyword(newToken);
typeTree = newClassTree.identifier();
} else {
NewArrayTreeImpl newArrayTree = (NewArrayTreeImpl) partial;
newArrayTree.completeWithNewKeyword(newToken);
typeTree = newArrayTree.type();
}
completeTypeTreeWithAnnotations(typeTree, annotations);
return partial;
}
public ExpressionTree newClassCreator(Optional typeArguments, TypeTree qualifiedIdentifier, NewClassTreeImpl classCreatorRest) {
if (typeArguments.isPresent()) {
classCreatorRest.completeWithTypeArguments(typeArguments.get());
}
return classCreatorRest.completeWithIdentifier(qualifiedIdentifier);
}
public ExpressionTree newArrayCreator(TypeTree type, NewArrayTreeImpl partial) {
return partial.complete(type);
}
public NewArrayTreeImpl completeArrayCreator(Optional> annotations, NewArrayTreeImpl partial) {
if (annotations.isPresent()) {
partial.completeFirstDimension(annotations.get());
}
return partial;
}
public NewArrayTreeImpl newArrayCreatorWithInitializer(
InternalSyntaxToken openBracketToken, InternalSyntaxToken closeBracketToken,
Optional>, Tuple>>> dimensions,
NewArrayTreeImpl partial) {
ImmutableList.Builder dDimensionsBuilder = ImmutableList.builder();
dDimensionsBuilder.add(new ArrayDimensionTreeImpl(openBracketToken, null, closeBracketToken));
if (dimensions.isPresent()) {
for (Tuple>, Tuple> dim : dimensions.get()) {
List annotations = dim.first().or(ImmutableList.of());
Tuple brackets = dim.second();
dDimensionsBuilder.add(new ArrayDimensionTreeImpl(annotations, brackets.first(), null, brackets.second()));
}
}
return partial.completeDimensions(dDimensionsBuilder.build());
}
public NewArrayTreeImpl newArrayCreatorWithDimension(InternalSyntaxToken openBracketToken, ExpressionTree expression, InternalSyntaxToken closeBracketToken,
Optional> arrayAccesses,
Optional>, Tuple>>> dims) {
ImmutableList.Builder dimensions = ImmutableList.builder();
dimensions.add(new ArrayDimensionTreeImpl(openBracketToken, expression, closeBracketToken));
if (arrayAccesses.isPresent()) {
for (ArrayAccessExpressionTreeImpl arrayAccess : arrayAccesses.get()) {
dimensions.add(arrayAccess.dimension());
}
}
if (dims.isPresent()) {
for (Tuple>, Tuple> dim : dims.get()) {
Tuple brackets = dim.second();
List annotations = dim.first().or(ImmutableList.of());
dimensions.add(new ArrayDimensionTreeImpl(annotations, brackets.first(), null, brackets.second()));
}
}
return new NewArrayTreeImpl(dimensions.build(), InitializerListTreeImpl.emptyList());
}
public ExpressionTree basicClassExpression(PrimitiveTypeTreeImpl basicType, Optional>> dimensions,
InternalSyntaxToken dotToken, InternalSyntaxToken classToken) {
// 15.8.2. Class Literals
// int.class
// int[].class
IdentifierTreeImpl classIdentifier = new IdentifierTreeImpl(classToken);
ArrayTypeTreeImpl nestedDimensions = newArrayTypeTree(dimensions);
TypeTree typeTree = applyDim(basicType, nestedDimensions);
return new MemberSelectExpressionTreeImpl((ExpressionTree) typeTree, dotToken, classIdentifier);
}
public PrimitiveTypeTreeImpl newBasicType(Optional> annotations, InternalSyntaxToken basicType) {
JavaTree.PrimitiveTypeTreeImpl primitiveTypeTree = new JavaTree.PrimitiveTypeTreeImpl(basicType);
completeTypeTreeWithAnnotations(primitiveTypeTree, annotations);
return primitiveTypeTree;
}
public ArgumentListTreeImpl completeArguments(InternalSyntaxToken openParenthesisToken, Optional expressions, InternalSyntaxToken closeParenthesisToken) {
return expressions.isPresent() ?
expressions.get().complete(openParenthesisToken, closeParenthesisToken) :
new ArgumentListTreeImpl(openParenthesisToken, closeParenthesisToken);
}
public ArgumentListTreeImpl newArguments(ExpressionTree expression, Optional>> rests) {
ImmutableList.Builder expressions = ImmutableList.builder();
expressions.add(expression);
ImmutableList.Builder separators = ImmutableList.builder();
if (rests.isPresent()) {
for (Tuple rest : rests.get()) {
separators.add(rest.first());
expressions.add(rest.second());
}
}
return new ArgumentListTreeImpl(expressions.build(), separators.build());
}
public TypeTree annotationIdentifier(InternalSyntaxToken firstIdentifier, Optional>> rests) {
List children = Lists.newArrayList();
children.add(firstIdentifier);
if (rests.isPresent()) {
for (Tuple rest : rests.get()) {
children.add(rest.first());
children.add(rest.second());
}
}
JavaTree result = null;
InternalSyntaxToken dotToken = null;
for (InternalSyntaxToken child : children) {
if (!child.getGrammarRuleKey().equals(JavaTokenType.IDENTIFIER)) {
dotToken = child;
} else {
InternalSyntaxToken identifierToken = child;
if (result == null) {
result = new IdentifierTreeImpl(identifierToken);
} else {
IdentifierTreeImpl identifier = new IdentifierTreeImpl(identifierToken);
result = new MemberSelectExpressionTreeImpl((ExpressionTree) result, dotToken, identifier);
}
}
}
return (TypeTree) result;
}
public T newQualifiedIdentifier(ExpressionTree firstIdentifier, Optional>> rests) {
ExpressionTree result = firstIdentifier;
if (rests.isPresent()) {
for (Tuple rest : rests.get()) {
InternalSyntaxToken dotToken = rest.first();
if (rest.second().is(Kind.IDENTIFIER)) {
result = new MemberSelectExpressionTreeImpl(result, dotToken, (IdentifierTreeImpl) rest.second());
} else if (rest.second().is(Kind.PARAMETERIZED_TYPE)) {
ParameterizedTypeTreeImpl parameterizedType = (ParameterizedTypeTreeImpl) rest.second();
IdentifierTreeImpl identifier = (IdentifierTreeImpl) parameterizedType.type();
result = new MemberSelectExpressionTreeImpl(result, dotToken, identifier);
result = new ParameterizedTypeTreeImpl((TypeTree) result, (TypeArgumentListTreeImpl) parameterizedType.typeArguments());
} else {
throw new IllegalArgumentException();
}
}
moveAnnotations(result, firstIdentifier);
}
return (T) result;
}
private static void moveAnnotations(ExpressionTree result, ExpressionTree firstIdentifier) {
List firstIdentifierAnnotations;
boolean isParameterizedType = firstIdentifier.is(Tree.Kind.PARAMETERIZED_TYPE);
if (isParameterizedType) {
firstIdentifierAnnotations = ((ParameterizedTypeTree) firstIdentifier).annotations();
} else {
firstIdentifierAnnotations = ((IdentifierTree) firstIdentifier).annotations();
}
// move the annotations from the first identifier to the member select or the parameterized type
if (!firstIdentifierAnnotations.isEmpty()) {
if (result.is(Tree.Kind.MEMBER_SELECT)) {
((MemberSelectExpressionTreeImpl) result).complete(firstIdentifierAnnotations);
} else {
((ParameterizedTypeTreeImpl) result).complete(firstIdentifierAnnotations);
}
if (isParameterizedType) {
((ParameterizedTypeTreeImpl) firstIdentifier).complete(ImmutableList.of());
} else {
((IdentifierTreeImpl) firstIdentifier).complete(ImmutableList.of());
}
}
}
public ExpressionTree newAnnotatedParameterizedIdentifier(
Optional> annotations, InternalSyntaxToken identifierToken, Optional typeArguments) {
List annotationList = annotations.isPresent() ?
ImmutableList.builder().addAll(annotations.get()).build() :
ImmutableList.of();
ExpressionTree result = new IdentifierTreeImpl(identifierToken);
if (typeArguments.isPresent()) {
result = new ParameterizedTypeTreeImpl((TypeTree) result, typeArguments.get()).complete(annotationList);
} else {
result = ((IdentifierTreeImpl) result).complete(annotationList);
}
return result;
}
public NewArrayTreeImpl newArrayInitializer(
InternalSyntaxToken openBraceToken,
Optional optionalComma,
Optional>>> rests,
InternalSyntaxToken closeBraceToken) {
ImmutableList.Builder initializers = ImmutableList.builder();
ImmutableList.Builder separators = ImmutableList.builder();
if (optionalComma.isPresent()) {
separators.add(optionalComma.get());
}
if (rests.isPresent()) {
for (Tuple> rest : rests.get()) {
initializers.add(rest.first());
if (rest.second().isPresent()) {
separators.add(rest.second().get());
}
}
}
return new NewArrayTreeImpl(ImmutableList.of(),
new InitializerListTreeImpl(initializers.build(), separators.build())).completeWithCurlyBraces(openBraceToken, closeBraceToken);
}
public QualifiedIdentifierListTreeImpl newQualifiedIdentifierList(TypeTree qualifiedIdentifier, Optional>> rests) {
ImmutableList.Builder qualifiedIdentifiers = ImmutableList.builder();
ImmutableList.Builder separators = ImmutableList.builder();
qualifiedIdentifiers.add(qualifiedIdentifier);
if (rests.isPresent()) {
for (Tuple rest : rests.get()) {
separators.add(rest.first());
qualifiedIdentifiers.add(rest.second());
}
}
return new QualifiedIdentifierListTreeImpl(qualifiedIdentifiers.build(), separators.build());
}
public ArrayAccessExpressionTreeImpl newArrayAccessExpression(Optional> annotations, InternalSyntaxToken openBracketToken, ExpressionTree index,
InternalSyntaxToken closeBracketToken) {
return new ArrayAccessExpressionTreeImpl(new ArrayDimensionTreeImpl(
annotations.or(ImmutableList.of()),
openBracketToken,
index,
closeBracketToken));
}
public NewClassTreeImpl newClassCreatorRest(ArgumentListTreeImpl arguments, Optional classBody) {
return new NewClassTreeImpl(arguments, classBody.orNull());
}
public ExpressionTree newIdentifierOrMethodInvocation(Optional typeArguments, InternalSyntaxToken identifierToken,
Optional arguments) {
IdentifierTreeImpl identifier = new IdentifierTreeImpl(identifierToken);
ExpressionTree result = identifier;
if (arguments.isPresent()) {
result = new MethodInvocationTreeImpl(identifier, typeArguments.orNull(), arguments.get());
}
return result;
}
public Tuple, ExpressionTree> completeMemberSelectOrMethodSelector(InternalSyntaxToken dotToken, ExpressionTree partial) {
return newTuple(Optional.of(dotToken), partial);
}
public Tuple, ExpressionTree> completeCreatorSelector(InternalSyntaxToken dotToken, ExpressionTree partial) {
((NewClassTreeImpl) partial).completeWithDotToken(dotToken);
return newTuple(Optional.absent(), partial);
}
public ExpressionTree newDotClassSelector(Optional>> dimensions,
InternalSyntaxToken dotToken, InternalSyntaxToken classToken) {
IdentifierTreeImpl identifier = new IdentifierTreeImpl(classToken);
ArrayTypeTreeImpl nestedDimensions = newArrayTypeTree(dimensions);
return new MemberSelectExpressionTreeImpl(nestedDimensions, dotToken, identifier);
}
private static ExpressionTree applySelectors(ExpressionTree primary, Optional, ExpressionTree>>> selectors) {
ExpressionTree result = primary;
if (selectors.isPresent()) {
for (Tuple, ExpressionTree> tuple : selectors.get()) {
Optional dotTokenOptional = tuple.first();
ExpressionTree selector = tuple.second();
if (dotTokenOptional.isPresent()) {
InternalSyntaxToken dotToken = dotTokenOptional.get();
if (selector.is(Kind.IDENTIFIER)) {
IdentifierTreeImpl identifier = (IdentifierTreeImpl) selector;
result = new MemberSelectExpressionTreeImpl(result, dotToken, identifier);
} else {
MethodInvocationTreeImpl methodInvocation = (MethodInvocationTreeImpl) selector;
IdentifierTreeImpl identifier = (IdentifierTreeImpl) methodInvocation.methodSelect();
MemberSelectExpressionTreeImpl memberSelect = new MemberSelectExpressionTreeImpl(result, dotToken, identifier);
result = new MethodInvocationTreeImpl(memberSelect, methodInvocation.typeArguments(), (ArgumentListTreeImpl) methodInvocation.arguments());
}
} else if (selector.is(Kind.NEW_CLASS)) {
NewClassTreeImpl newClass = (NewClassTreeImpl) selector;
result = newClass.completeWithEnclosingExpression(result);
} else if (selector.is(Kind.ARRAY_ACCESS_EXPRESSION)) {
ArrayAccessExpressionTreeImpl arrayAccess = (ArrayAccessExpressionTreeImpl) selector;
result = arrayAccess.complete(result);
} else if (selector.is(Kind.MEMBER_SELECT)) {
MemberSelectExpressionTreeImpl memberSelect = (MemberSelectExpressionTreeImpl) selector;
result = memberSelect.completeWithExpression(result);
} else {
throw new IllegalStateException();
}
}
}
return result;
}
public ExpressionTree applySelectors1(ExpressionTree primary, Optional, ExpressionTree>>> selectors) {
return applySelectors(primary, selectors);
}
public ExpressionTree applySelectors2(ExpressionTree primary, Optional, ExpressionTree>>> selectors) {
return applySelectors(primary, selectors);
}
// End of expressions
// Helpers
public static class Tuple {
private final T first;
private final U second;
public Tuple(T first, U second) {
this.first = first;
this.second = second;
}
public T first() {
return first;
}
public U second() {
return second;
}
}
private Tuple newTuple(T first, U second) {
return new Tuple<>(first, second);
}
public Tuple newTuple1(T first, U second) {
return newTuple(first, second);
}
public Tuple newTuple2(T first, U second) {
return newTuple(first, second);
}
public Tuple newTuple3(T first, U second) {
return newTuple(first, second);
}
public Tuple newTuple4(T first, U second) {
return newTuple(first, second);
}
public Tuple newTuple5(T first, U second) {
return newTuple(first, second);
}
public Tuple newTuple6(T first, U second) {
return newTuple(first, second);
}
public Tuple newTuple7(T first, U second) {
return newTuple(first, second);
}
public Tuple newTuple8(T first, U second) {
return newTuple(first, second);
}
public