|
21 | 21 | import java.util.Collections; |
22 | 22 | import java.util.LinkedHashSet; |
23 | 23 | import java.util.List; |
| 24 | +import java.util.Set; |
24 | 25 | import java.util.stream.Collectors; |
25 | 26 | import javax.annotation.Nullable; |
26 | 27 |
|
@@ -169,6 +170,8 @@ public Builder setReturnExpr(Expr expr) { |
169 | 170 | // Private accessors. |
170 | 171 | abstract String name(); |
171 | 172 |
|
| 173 | + abstract ImmutableList<VariableExpr> arguments(); |
| 174 | + |
172 | 175 | abstract ImmutableList<CommentStatement> headerCommentStatements(); |
173 | 176 |
|
174 | 177 | abstract ImmutableList<AnnotationNode> annotations(); |
@@ -314,28 +317,66 @@ public MethodDefinition build() { |
314 | 317 | } |
315 | 318 | } |
316 | 319 |
|
317 | | - for (VariableExpr varExpr : method.arguments()) { |
318 | | - Preconditions.checkState( |
319 | | - varExpr.isDecl(), |
320 | | - String.format( |
321 | | - "Argument %s must be a variable declaration", varExpr.variable().identifier())); |
322 | | - } |
323 | | - |
324 | | - for (TypeNode exceptionType : method.throwsExceptions()) { |
325 | | - Preconditions.checkState( |
326 | | - TypeNode.isExceptionType(exceptionType), |
327 | | - String.format("Type %s is not an exception type", exceptionType.reference())); |
328 | | - Preconditions.checkState( |
329 | | - !RUNTIME_EXCEPTION_REFERENCE.isAssignableFrom(exceptionType.reference()), |
330 | | - String.format( |
331 | | - "RuntimeException type %s does not need to be thrown", |
332 | | - exceptionType.reference().name())); |
333 | | - } |
| 320 | + performArgumentChecks(); |
| 321 | + performThrownExceptionChecks(); |
334 | 322 |
|
335 | 323 | return method; |
336 | 324 | } |
337 | 325 |
|
338 | | - void performNullChecks() { |
| 326 | + private void performArgumentChecks() { |
| 327 | + // Must be a declaration. |
| 328 | + arguments().stream() |
| 329 | + .forEach( |
| 330 | + varExpr -> |
| 331 | + Preconditions.checkState( |
| 332 | + varExpr.isDecl(), |
| 333 | + String.format( |
| 334 | + "Argument %s must be a variable declaration", |
| 335 | + varExpr.variable().identifier()))); |
| 336 | + // No modifiers allowed. |
| 337 | + arguments().stream() |
| 338 | + .forEach( |
| 339 | + varExpr -> |
| 340 | + Preconditions.checkState( |
| 341 | + varExpr.scope().equals(ScopeNode.LOCAL) |
| 342 | + && !varExpr.isStatic() |
| 343 | + && !varExpr.isVolatile(), |
| 344 | + String.format( |
| 345 | + "Argument %s must have local scope, and cannot have \"static\" or" |
| 346 | + + " \"volatile\" modifiers", |
| 347 | + varExpr.variable().identifier()))); |
| 348 | + |
| 349 | + // Check that there aren't any arguments with duplicate names. |
| 350 | + List<String> allArgNames = |
| 351 | + arguments().stream() |
| 352 | + .map(v -> v.variable().identifier().name()) |
| 353 | + .collect(Collectors.toList()); |
| 354 | + Set<String> duplicateArgNames = |
| 355 | + allArgNames.stream() |
| 356 | + .filter(n -> Collections.frequency(allArgNames, n) > 1) |
| 357 | + .collect(Collectors.toSet()); |
| 358 | + Preconditions.checkState( |
| 359 | + duplicateArgNames.isEmpty(), |
| 360 | + String.format( |
| 361 | + "Lambda arguments cannot have duplicate names: %s", duplicateArgNames.toString())); |
| 362 | + } |
| 363 | + |
| 364 | + private void performThrownExceptionChecks() { |
| 365 | + throwsExceptions().stream() |
| 366 | + .forEach( |
| 367 | + exceptionType -> { |
| 368 | + Preconditions.checkState( |
| 369 | + TypeNode.isExceptionType(exceptionType), |
| 370 | + String.format("Type %s is not an exception type", exceptionType.reference())); |
| 371 | + Preconditions.checkState( |
| 372 | + !RUNTIME_EXCEPTION_REFERENCE.isAssignableFrom(exceptionType.reference()), |
| 373 | + String.format( |
| 374 | + "RuntimeException type %s does not need to be thrown", |
| 375 | + exceptionType.reference().name())); |
| 376 | + }); |
| 377 | + } |
| 378 | + |
| 379 | + private void performNullChecks() { |
339 | 380 | String contextInfo = String.format("method definition of %s", name()); |
340 | 381 | NodeValidator.checkNoNullElements(headerCommentStatements(), "header comments", contextInfo); |
341 | 382 | NodeValidator.checkNoNullElements(annotations(), "annotations", contextInfo); |
|
0 commit comments