468 return ", " + nodeType.nodeClass + "_positions, " + !nodeType.shareable + ")";
469 }
470 if (nodeType.shareable) {
471 return ", false)";
472 }
473 }
474 }
475 return ")";
476 }
477
478 String generatePositionDeclaration() {
479 return String.format("Position[] %s_positions = MatchRuleRegistry.findPositions(%s.TYPE, new String[]{\"%s\"});", nodeType.nodeClass, nodeType.nodeClass,
480 String.join("\", \"", nodeType.inputs));
481 }
482 }
483
484 /**
485 * Strip the package off a class name leaving the full class name including any outer classes.
486 */
487 private String fullClassName(Element element) {
488 assert element.getKind() == ElementKind.CLASS || element.getKind() == ElementKind.INTERFACE : element;
489 String pkg = findPackage(element);
490 return ((TypeElement) element).getQualifiedName().toString().substring(pkg.length() + 1);
491 }
492
493 private void createFiles(MatchRuleDescriptor info) {
494 String pkg = ((PackageElement) info.topDeclaringType.getEnclosingElement()).getQualifiedName().toString();
495 Name topDeclaringClass = info.topDeclaringType.getSimpleName();
496
497 String matchStatementClassName = topDeclaringClass + "_MatchStatementSet";
498 Element[] originatingElements = info.originatingElements.toArray(new Element[info.originatingElements.size()]);
499
500 Types typeUtils = typeUtils();
501 Filer filer = processingEnv.getFiler();
502 try (PrintWriter out = createSourceFile(pkg, matchStatementClassName, filer, originatingElements)) {
503
504 out.println("// CheckStyle: stop header check");
505 out.println("// CheckStyle: stop line length check");
506 out.println("// GENERATED CONTENT - DO NOT EDIT");
507 out.println("// Source: " + topDeclaringClass + ".java");
508 out.println("package " + pkg + ";");
658
659 /**
660 * The mapping between elements with MatchRules and the wrapper class used invoke the code
661 * generation after the match.
662 */
663 Map<String, MethodInvokerItem> invokers = new HashMap<>();
664
665 /**
666 * The set of packages which must be imported to refer the classes mentioned in matchRules.
667 */
668 Set<String> requiredPackages = new HashSet<>();
669
670 MatchRuleDescriptor(TypeElement topDeclaringType) {
671 this.topDeclaringType = topDeclaringType;
672 }
673 }
674
675 private static TypeElement topDeclaringType(Element element) {
676 Element enclosing = element.getEnclosingElement();
677 if (enclosing == null || enclosing.getKind() == ElementKind.PACKAGE) {
678 assert element.getKind() == ElementKind.CLASS || element.getKind() == ElementKind.INTERFACE;
679 return (TypeElement) element;
680 }
681 return topDeclaringType(enclosing);
682 }
683
684 /**
685 * The element currently being processed.
686 */
687 private Element currentElement;
688
689 /**
690 * The current processing round.
691 */
692 private RoundEnvironment currentRound;
693
694 @Override
695 public boolean doProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
696 if (roundEnv.processingOver()) {
697 return true;
698 }
943
944 String methodName = method.getSimpleName().toString();
945 MethodInvokerItem invoker = info.invokers.get(methodName);
946 if (invoker == null) {
947 invoker = new MethodInvokerItem(methodName, topDeclaringType(method).getSimpleName().toString(), method, actualParameters);
948 info.invokers.put(methodName, invoker);
949 } else if (invoker.method != method) {
950 // This could be supported but it's easier if they are unique since the names
951 // are used in log output and snippet counters.
952 printError(method, "Use unique method names for match methods: %s.%s != %s.%s", method.getReceiverType(), method.getSimpleName(), invoker.method.getReceiverType(),
953 invoker.method.getSimpleName());
954 return;
955 }
956
957 Element enclosing = method.getEnclosingElement();
958 String declaringClass = "";
959 String separator = "";
960 Set<Element> originatingElementsList = info.originatingElements;
961 originatingElementsList.add(method);
962 while (enclosing != null) {
963 if (enclosing.getKind() == ElementKind.CLASS || enclosing.getKind() == ElementKind.INTERFACE) {
964 if (enclosing.getModifiers().contains(Modifier.PRIVATE)) {
965 printError(method, "MatchRule cannot be declared in a private %s %s", enclosing.getKind().name().toLowerCase(), enclosing);
966 return;
967 }
968 originatingElementsList.add(enclosing);
969 declaringClass = enclosing.getSimpleName() + separator + declaringClass;
970 separator = ".";
971 } else {
972 assert enclosing.getKind() == ElementKind.PACKAGE;
973 }
974 enclosing = enclosing.getEnclosingElement();
975 }
976
977 originatingElementsList.addAll(parser.originatingElements);
978 info.requiredPackages.addAll(parser.requiredPackages);
979
980 // Accumulate any position declarations.
981 parser.generatePositionDeclarations(info.positionDeclarations);
982
983 List<String> matches = parser.generateVariants();
984 for (String match : matches) {
985 info.matchRules.add(new MatchRuleItem(match, invoker));
986 }
987 } catch (RuleParseError e) {
988 printError(method, matchRule, e.getMessage());
989 }
990 }
991
992 private Element elementForMessage(Element e) {
|
468 return ", " + nodeType.nodeClass + "_positions, " + !nodeType.shareable + ")";
469 }
470 if (nodeType.shareable) {
471 return ", false)";
472 }
473 }
474 }
475 return ")";
476 }
477
478 String generatePositionDeclaration() {
479 return String.format("Position[] %s_positions = MatchRuleRegistry.findPositions(%s.TYPE, new String[]{\"%s\"});", nodeType.nodeClass, nodeType.nodeClass,
480 String.join("\", \"", nodeType.inputs));
481 }
482 }
483
484 /**
485 * Strip the package off a class name leaving the full class name including any outer classes.
486 */
487 private String fullClassName(Element element) {
488 String pkg = findPackage(element);
489 return ((TypeElement) element).getQualifiedName().toString().substring(pkg.length() + 1);
490 }
491
492 private void createFiles(MatchRuleDescriptor info) {
493 String pkg = ((PackageElement) info.topDeclaringType.getEnclosingElement()).getQualifiedName().toString();
494 Name topDeclaringClass = info.topDeclaringType.getSimpleName();
495
496 String matchStatementClassName = topDeclaringClass + "_MatchStatementSet";
497 Element[] originatingElements = info.originatingElements.toArray(new Element[info.originatingElements.size()]);
498
499 Types typeUtils = typeUtils();
500 Filer filer = processingEnv.getFiler();
501 try (PrintWriter out = createSourceFile(pkg, matchStatementClassName, filer, originatingElements)) {
502
503 out.println("// CheckStyle: stop header check");
504 out.println("// CheckStyle: stop line length check");
505 out.println("// GENERATED CONTENT - DO NOT EDIT");
506 out.println("// Source: " + topDeclaringClass + ".java");
507 out.println("package " + pkg + ";");
657
658 /**
659 * The mapping between elements with MatchRules and the wrapper class used invoke the code
660 * generation after the match.
661 */
662 Map<String, MethodInvokerItem> invokers = new HashMap<>();
663
664 /**
665 * The set of packages which must be imported to refer the classes mentioned in matchRules.
666 */
667 Set<String> requiredPackages = new HashSet<>();
668
669 MatchRuleDescriptor(TypeElement topDeclaringType) {
670 this.topDeclaringType = topDeclaringType;
671 }
672 }
673
674 private static TypeElement topDeclaringType(Element element) {
675 Element enclosing = element.getEnclosingElement();
676 if (enclosing == null || enclosing.getKind() == ElementKind.PACKAGE) {
677 return (TypeElement) element;
678 }
679 return topDeclaringType(enclosing);
680 }
681
682 /**
683 * The element currently being processed.
684 */
685 private Element currentElement;
686
687 /**
688 * The current processing round.
689 */
690 private RoundEnvironment currentRound;
691
692 @Override
693 public boolean doProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
694 if (roundEnv.processingOver()) {
695 return true;
696 }
941
942 String methodName = method.getSimpleName().toString();
943 MethodInvokerItem invoker = info.invokers.get(methodName);
944 if (invoker == null) {
945 invoker = new MethodInvokerItem(methodName, topDeclaringType(method).getSimpleName().toString(), method, actualParameters);
946 info.invokers.put(methodName, invoker);
947 } else if (invoker.method != method) {
948 // This could be supported but it's easier if they are unique since the names
949 // are used in log output and snippet counters.
950 printError(method, "Use unique method names for match methods: %s.%s != %s.%s", method.getReceiverType(), method.getSimpleName(), invoker.method.getReceiverType(),
951 invoker.method.getSimpleName());
952 return;
953 }
954
955 Element enclosing = method.getEnclosingElement();
956 String declaringClass = "";
957 String separator = "";
958 Set<Element> originatingElementsList = info.originatingElements;
959 originatingElementsList.add(method);
960 while (enclosing != null) {
961 if (enclosing.getKind() == ElementKind.CLASS || enclosing.getKind() == ElementKind.INTERFACE || enclosing.getKind() == ElementKind.ENUM) {
962 if (enclosing.getModifiers().contains(Modifier.PRIVATE)) {
963 printError(method, "MatchRule cannot be declared in a private %s %s", enclosing.getKind().name().toLowerCase(), enclosing);
964 return;
965 }
966 originatingElementsList.add(enclosing);
967 declaringClass = enclosing.getSimpleName() + separator + declaringClass;
968 separator = ".";
969 } else if (enclosing.getKind() == ElementKind.PACKAGE) {
970 break;
971 } else {
972 printError(method, "MatchRule cannot be declared in a %s", enclosing.getKind().name().toLowerCase());
973 return;
974 }
975 enclosing = enclosing.getEnclosingElement();
976 }
977
978 originatingElementsList.addAll(parser.originatingElements);
979 info.requiredPackages.addAll(parser.requiredPackages);
980
981 // Accumulate any position declarations.
982 parser.generatePositionDeclarations(info.positionDeclarations);
983
984 List<String> matches = parser.generateVariants();
985 for (String match : matches) {
986 info.matchRules.add(new MatchRuleItem(match, invoker));
987 }
988 } catch (RuleParseError e) {
989 printError(method, matchRule, e.getMessage());
990 }
991 }
992
993 private Element elementForMessage(Element e) {
|