Skip to content

Commit

Permalink
Merge branch 'master' into fix/pubsub
Browse files Browse the repository at this point in the history
  • Loading branch information
miraleung authored May 26, 2021
2 parents 4e19c30 + c4561c9 commit 107018a
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

Expand Down Expand Up @@ -169,6 +170,8 @@ public Builder setReturnExpr(Expr expr) {
// Private accessors.
abstract String name();

abstract ImmutableList<VariableExpr> arguments();

abstract ImmutableList<CommentStatement> headerCommentStatements();

abstract ImmutableList<AnnotationNode> annotations();
Expand Down Expand Up @@ -314,28 +317,66 @@ public MethodDefinition build() {
}
}

for (VariableExpr varExpr : method.arguments()) {
Preconditions.checkState(
varExpr.isDecl(),
String.format(
"Argument %s must be a variable declaration", varExpr.variable().identifier()));
}

for (TypeNode exceptionType : method.throwsExceptions()) {
Preconditions.checkState(
TypeNode.isExceptionType(exceptionType),
String.format("Type %s is not an exception type", exceptionType.reference()));
Preconditions.checkState(
!RUNTIME_EXCEPTION_REFERENCE.isAssignableFrom(exceptionType.reference()),
String.format(
"RuntimeException type %s does not need to be thrown",
exceptionType.reference().name()));
}
performArgumentChecks();
performThrownExceptionChecks();

return method;
}

void performNullChecks() {
private void performArgumentChecks() {
// Must be a declaration.
arguments().stream()
.forEach(
varExpr ->
Preconditions.checkState(
varExpr.isDecl(),
String.format(
"Argument %s must be a variable declaration",
varExpr.variable().identifier())));
// No modifiers allowed.
arguments().stream()
.forEach(
varExpr ->
Preconditions.checkState(
varExpr.scope().equals(ScopeNode.LOCAL)
&& !varExpr.isStatic()
&& !varExpr.isVolatile(),
String.format(
"Argument %s must have local scope, and cannot have \"static\" or"
+ " \"volatile\" modifiers",
varExpr.variable().identifier())));

// Check that there aren't any arguments with duplicate names.
List<String> allArgNames =
arguments().stream()
.map(v -> v.variable().identifier().name())
.collect(Collectors.toList());
Set<String> duplicateArgNames =
allArgNames.stream()
.filter(n -> Collections.frequency(allArgNames, n) > 1)
.collect(Collectors.toSet());
Preconditions.checkState(
duplicateArgNames.isEmpty(),
String.format(
"Lambda arguments cannot have duplicate names: %s", duplicateArgNames.toString()));
}

private void performThrownExceptionChecks() {
throwsExceptions().stream()
.forEach(
exceptionType -> {
Preconditions.checkState(
TypeNode.isExceptionType(exceptionType),
String.format("Type %s is not an exception type", exceptionType.reference()));
Preconditions.checkState(
!RUNTIME_EXCEPTION_REFERENCE.isAssignableFrom(exceptionType.reference()),
String.format(
"RuntimeException type %s does not need to be thrown",
exceptionType.reference().name()));
});
}

private void performNullChecks() {
String contextInfo = String.format("method definition of %s", name());
NodeValidator.checkNoNullElements(headerCommentStatements(), "header comments", contextInfo);
NodeValidator.checkNoNullElements(annotations(), "annotations", contextInfo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ public void validMethodDefinition_basicWithComments() {
// No exception thrown, we're good.
}

@Test
public void validMethodDefinition_emptyBody() {
MethodDefinition.builder()
.setHeaderCommentStatements(createCommentStatements())
.setName("close")
.setScope(ScopeNode.PUBLIC)
.setReturnType(TypeNode.VOID)
.build();
}

@Test
public void validMethodDefinition_repeatedAnnotations() {
MethodDefinition method =
Expand Down Expand Up @@ -86,7 +96,6 @@ public void validMethodDefinition_throwInsteadOfReturnType() {
ConcreteReference.withClazz(NullPointerException.class)))
.build())))
.build();
// No exception thrown, we're good.
}

@Test
Expand All @@ -105,7 +114,6 @@ public void validMethodDefinition_voidThrowInsteadOfReturnType() {
ConcreteReference.withClazz(NullPointerException.class)))
.build())))
.build();
// No exception thrown, we're good.
}

@Test
Expand Down Expand Up @@ -645,6 +653,30 @@ public void invalidMethodDefinition_mismatchedPrimitiveToObjectReturnType() {
});
}

@Test
public void invalidMethodDefinition_repeatedArgumentName() {
ValueExpr returnValueExpr =
ValueExpr.builder()
.setValue(PrimitiveValue.builder().setType(TypeNode.INT).setValue("3").build())
.build();
List<VariableExpr> arguments =
Arrays.asList(
VariableExpr.builder().setVariable(createVariable("x", TypeNode.INT)).build(),
VariableExpr.builder().setVariable(createVariable("x", TypeNode.STRING)).build());
assertThrows(
IllegalStateException.class,
() -> {
MethodDefinition.builder()
.setName("close")
.setScope(ScopeNode.PUBLIC)
.setReturnType(TypeNode.INT)
.setArguments(arguments)
.setReturnExpr(returnValueExpr)
.setBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr())))
.build();
});
}

@Test
public void invalidMethodDefinition_nonDeclArguments() {
ValueExpr returnValueExpr =
Expand All @@ -669,6 +701,59 @@ public void invalidMethodDefinition_nonDeclArguments() {
});
}

@Test
public void invalidMethodDefinition_argumentsWithModifiers() {
ValueExpr returnValueExpr =
ValueExpr.builder()
.setValue(PrimitiveValue.builder().setType(TypeNode.INT).setValue("3").build())
.build();
List<VariableExpr> arguments =
Arrays.asList(
VariableExpr.builder()
.setVariable(createVariable("x", TypeNode.INT))
.setIsDecl(true)
.setIsStatic(true)
.build(),
VariableExpr.builder().setVariable(createVariable("y", TypeNode.INT)).build());
assertThrows(
IllegalStateException.class,
() -> {
MethodDefinition.builder()
.setName("close")
.setScope(ScopeNode.PUBLIC)
.setReturnType(TypeNode.INT)
.setArguments(arguments)
.setReturnExpr(returnValueExpr)
.build();
});
}

@Test
public void invalidMethodDefinition_argumentsWithScope() {
ValueExpr returnValueExpr =
ValueExpr.builder()
.setValue(PrimitiveValue.builder().setType(TypeNode.INT).setValue("3").build())
.build();
List<VariableExpr> arguments =
Arrays.asList(
VariableExpr.builder().setVariable(createVariable("x", TypeNode.INT)).build(),
VariableExpr.builder()
.setVariable(createVariable("y", TypeNode.INT))
.setScope(ScopeNode.PRIVATE)
.build());
assertThrows(
IllegalStateException.class,
() -> {
MethodDefinition.builder()
.setName("close")
.setScope(ScopeNode.PUBLIC)
.setReturnType(TypeNode.INT)
.setArguments(arguments)
.setReturnExpr(returnValueExpr)
.build();
});
}

@Test
public void invalidMethodDefinition_nullReturnType() {
assertThrows(
Expand Down

0 comments on commit 107018a

Please sign in to comment.