Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

review: refactor: replace direct access to ContextBuilder#stack with methods #5241

Merged
merged 2 commits into from
Jun 1, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 35 additions & 4 deletions src/main/java/spoon/support/compiler/jdt/ContextBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
/**
* Stack of all parents elements
*/
Deque<ASTPair> stack = new ArrayDeque<>();
private Deque<ASTPair> stack = new ArrayDeque<>();

Check warning on line 78 in src/main/java/spoon/support/compiler/jdt/ContextBuilder.java

View workflow job for this annotation

GitHub Actions / code-quality qodana

Field may be 'final'

Field `stack` may be 'final'

private final JDTTreeBuilder jdtTreeBuilder;

Expand Down Expand Up @@ -130,6 +130,37 @@
}
}

/**
* @return all {@link ASTPair}s currently on the stack
SirYwell marked this conversation as resolved.
Show resolved Hide resolved
*/
Iterable<ASTPair> getAllContexts() {
return stack;
}

/**
* @return {@code true} if there are any elements on the stack
SirYwell marked this conversation as resolved.
Show resolved Hide resolved
*/
boolean hasCurrentContext() {
return !stack.isEmpty();
}

/**
*
* @return the {@link CtElement} on the top of the stack
* @throws NullPointerException if the stack is empty
*/
CtElement getCurrentElement() {
return stack.peek().element;
}

/**
* @return the {@link ASTNode} on the top of the stack
* @throws NullPointerException if the stack is empty
*/
ASTNode getCurrentNode() {
return stack.peek().node;
}

CtElement getContextElementOnLevel(int level) {
for (ASTPair pair : stack) {
if (level == 0) {
Expand Down Expand Up @@ -168,7 +199,7 @@
// note: this happens when using the new try(vardelc) structure
this.jdtTreeBuilder.getLogger().error(
format("Could not find declaration for local variable %s at %s",
name, stack.peek().element.getPosition()));
name, getCurrentElement().getPosition()));
}
return localVariable;
}
Expand All @@ -183,7 +214,7 @@
// note: this happens when using the new try(vardelc) structure
this.jdtTreeBuilder.getLogger().error(
format("Could not find declaration for catch variable %s at %s",
name, stack.peek().element.getPosition()));
name, getCurrentElement().getPosition()));
}
return catchVariable;
}
Expand All @@ -195,7 +226,7 @@
// note: this can happen when identifier is not a variable name but e.g. a Type name.
this.jdtTreeBuilder.getLogger().debug(
format("Could not find declaration for variable %s at %s.",
name, stack.peek().element.getPosition()));
name, getCurrentElement().getPosition()));
}
return variable;
}
Expand Down
44 changes: 21 additions & 23 deletions src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -449,8 +449,7 @@ public void endVisit(IntLiteral intLiteral, BlockScope scope) {

@Override
public void endVisit(LabeledStatement labeledStatement, BlockScope scope) {
ASTPair pair = context.stack.peek();
CtBlock<?> block = (CtBlock<?>) pair.element;
CtBlock<?> block = (CtBlock<?>) context.getCurrentElement();
if (block.getStatements().size() == 1) {
CtStatement childStmt = block.getStatement(0);
if (childStmt.getLabel() == null) {
Expand Down Expand Up @@ -610,7 +609,7 @@ public void endVisit(QualifiedAllocationExpression qualifiedAllocationExpression

@Override
public void endVisit(QualifiedNameReference qualifiedNameReference, BlockScope scope) {
if (context.stack.peek().node == qualifiedNameReference) {
if (context.getCurrentNode() == qualifiedNameReference) {
context.exit(qualifiedNameReference);
}
}
Expand Down Expand Up @@ -650,7 +649,7 @@ public void endVisit(SingleMemberAnnotation annotation, BlockScope scope) {

@Override
public void endVisit(SingleNameReference singleNameReference, BlockScope scope) {
if (context.stack.peek().node == singleNameReference) {
if (context.getCurrentNode() == singleNameReference) {
context.exit(singleNameReference);
}
}
Expand Down Expand Up @@ -706,16 +705,16 @@ public void endVisit(ThisReference thisReference, BlockScope scope) {

@Override
public void endVisit(SwitchStatement switchStatement, BlockScope scope) {
if (context.stack.peek().node instanceof CaseStatement) {
context.exit(context.stack.peek().node);
if (context.getCurrentNode() instanceof CaseStatement) {
context.exit(context.getCurrentNode());
}
context.exit(switchStatement);
}

@Override
public void endVisit(SwitchExpression switchExpression, BlockScope scope) {
if (context.stack.peek().node instanceof CaseStatement) {
context.exit(context.stack.peek().node);
if (context.getCurrentNode() instanceof CaseStatement) {
context.exit(context.getCurrentNode());
}
context.exit(switchExpression);
}
Expand Down Expand Up @@ -757,14 +756,14 @@ public void endVisit(TypeDeclaration localTypeDeclaration, BlockScope scope) {

@Override
public void endVisit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
while (!context.stack.isEmpty() && context.stack.peek().node == memberTypeDeclaration) {
while (context.hasCurrentContext() && context.getCurrentNode() == memberTypeDeclaration) {
context.exit(memberTypeDeclaration);
}
}

@Override
public void endVisit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
while (!context.stack.isEmpty() && context.stack.peek().node == typeDeclaration) {
while (context.hasCurrentContext() && context.getCurrentNode() == typeDeclaration) {
context.exit(typeDeclaration);
}
}
Expand Down Expand Up @@ -879,11 +878,10 @@ public void endVisit(LambdaExpression lambdaExpression, BlockScope blockScope) {
public boolean visit(AllocationExpression allocationExpression, BlockScope scope) {
CtConstructorCall constructorCall = factory.Core().createConstructorCall();
constructorCall.setExecutable(references.getExecutableReference(allocationExpression));
ASTPair first = this.context.stack.getFirst();

// in case of enum values the constructor call is often implicit
if (first.element instanceof CtEnumValue) {
if (allocationExpression.sourceEnd == first.node.sourceEnd) {
if (context.getCurrentElement() instanceof CtEnumValue) {
if (allocationExpression.sourceEnd == context.getCurrentNode().sourceEnd) {
constructorCall.setImplicit(true);
}
}
Expand Down Expand Up @@ -937,7 +935,7 @@ public boolean visit(AnnotationMethodDeclaration annotationMethodDeclaration, Cl

@Override
public boolean visit(Argument argument, BlockScope scope) {
if (this.getContextBuilder().stack.peekFirst().element instanceof CtTry) {
if (context.getCurrentElement() instanceof CtTry) {
context.enter(factory.Core().createCatch(), argument);
return true;
}
Expand Down Expand Up @@ -1547,14 +1545,14 @@ public boolean visit(QualifiedTypeReference qualifiedTypeReference, BlockScope s
if (skipTypeInAnnotation) {
return true;
}
if (context.stack.peekFirst().node instanceof UnionTypeReference) {
if (context.getCurrentNode() instanceof UnionTypeReference) {
CtTypeReference<Throwable> reference = references.<Throwable>getTypeReference(qualifiedTypeReference.resolvedType);
if (reference == null) {
reference = getFactory().createReference(qualifiedTypeReference.toString());
}
context.enter(reference, qualifiedTypeReference);
return true;
} else if (context.stack.peekFirst().element instanceof CtCatch) {
} else if (context.getCurrentElement() instanceof CtCatch) {
context.enter(helper.createCatchVariable(qualifiedTypeReference, scope), qualifiedTypeReference);
return true;
}
Expand Down Expand Up @@ -1586,7 +1584,7 @@ public boolean visit(SingleNameReference singleNameReference, BlockScope scope)
} else if (singleNameReference.binding instanceof TypeBinding) {
context.enter(factory.Code().createTypeAccessWithoutCloningReference(references.getTypeReference((TypeBinding) singleNameReference.binding).setSimplyQualified(true)), singleNameReference);
} else if (singleNameReference.binding instanceof ProblemBinding) {
if (context.stack.peek().element instanceof CtInvocation && Character.isUpperCase(CharOperation.charToString(singleNameReference.token).charAt(0))) {
if (context.getCurrentElement() instanceof CtInvocation && Character.isUpperCase(CharOperation.charToString(singleNameReference.token).charAt(0))) {
context.enter(helper.createTypeAccessNoClasspath(singleNameReference), singleNameReference);
} else {
context.enter(helper.createFieldAccessNoClasspath(singleNameReference), singleNameReference);
Expand Down Expand Up @@ -1640,7 +1638,7 @@ public void endVisit(UnionTypeReference unionTypeReference, ClassScope scope) {

@Override
public boolean visit(UnionTypeReference unionTypeReference, BlockScope scope) {
if (!(context.stack.peekFirst().node instanceof Argument)) {
if (!(context.getCurrentNode() instanceof Argument)) {
throw new SpoonException("UnionType is only supported for CtCatch.");
}
context.enter(helper.createCatchVariable(unionTypeReference, scope), unionTypeReference);
Expand All @@ -1657,7 +1655,7 @@ public boolean visit(SingleTypeReference singleTypeReference, BlockScope scope)
if (skipTypeInAnnotation) {
return true;
}
if (context.stack.peekFirst().node instanceof UnionTypeReference) {
if (context.getCurrentNode() instanceof UnionTypeReference) {
CtTypeReference<?> typeReference;

if (singleTypeReference.resolvedType == null) {
Expand All @@ -1671,10 +1669,10 @@ public boolean visit(SingleTypeReference singleTypeReference, BlockScope scope)
context.enter(typeReference, singleTypeReference);
typeReference.setSimplyQualified(true);
return true;
} else if (context.stack.peekFirst().element instanceof CtCatch) {
} else if (context.getCurrentElement() instanceof CtCatch) {
context.enter(helper.createCatchVariable(singleTypeReference, scope), singleTypeReference);
return true;
} else if (context.stack.getFirst().element instanceof CtExecutableReferenceExpression) {
} else if (context.getCurrentElement() instanceof CtExecutableReferenceExpression) {
context.enter(references.getTypeParameterReference(singleTypeReference.resolvedType, singleTypeReference), singleTypeReference);
return true;
}
Expand Down Expand Up @@ -1710,8 +1708,8 @@ public boolean visit(StringLiteralConcatenation literal, BlockScope scope) {

@Override
public boolean visit(CaseStatement caseStatement, BlockScope scope) {
if (context.stack.peek().node instanceof CaseStatement) {
context.exit(context.stack.peek().node);
if (context.getCurrentNode() instanceof CaseStatement) {
context.exit(context.getCurrentNode());
}

context.enter(factory.Core().createCase(), caseStatement);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ static String createQualifiedTypeName(char[][] typeName) {
* @return a catch variable.
*/
CtCatchVariable<Throwable> createCatchVariable(TypeReference typeReference, Scope scope) {
final Argument jdtCatch = (Argument) jdtTreeBuilder.getContextBuilder().stack.peekFirst().node;
final Argument jdtCatch = (Argument) jdtTreeBuilder.getContextBuilder().getCurrentNode();
final Set<CtExtendedModifier> modifiers = getModifiers(jdtCatch.modifiers, false, ModifierTarget.LOCAL_VARIABLE);

CtCatchVariable<Throwable> result = jdtTreeBuilder.getFactory().Core().createCatchVariable();
Expand Down Expand Up @@ -215,7 +215,7 @@ <T> CtVariableAccess<T> createVariableAccessNoClasspath(SingleNameReference sing

// find executable's corresponding jdt element
AbstractMethodDeclaration executableJDT = null;
for (final ASTPair astPair : contextBuilder.stack) {
for (final ASTPair astPair : contextBuilder.getAllContexts()) {
if (astPair.element == executable) {
executableJDT = (AbstractMethodDeclaration) astPair.node;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ static boolean isResolvedField(QualifiedNameReference qualifiedNameReference) {
* @return true if the lhs is equals to the given expression.
*/
static boolean isLhsAssignment(ContextBuilder context, Expression lhs) {
return context.stack.peek().node instanceof Assignment && ((Assignment) context.stack.peek().node).lhs.equals(lhs);
return context.getCurrentNode() instanceof Assignment && ((Assignment) context.getCurrentNode()).lhs.equals(lhs);
}

/**
Expand Down