diff --git a/.github/workflows/gen_io_types.yml b/.github/workflows/main.yml
similarity index 59%
rename from .github/workflows/gen_io_types.yml
rename to .github/workflows/main.yml
index f4642f6..88f6c0e 100644
--- a/.github/workflows/gen_io_types.yml
+++ b/.github/workflows/main.yml
@@ -5,36 +5,6 @@ on:
permissions:
contents: write
jobs:
- gen_io_types:
- runs-on: ubuntu-latest
- env:
- # This line prevents the action from running after an automated push.
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- steps:
- # Check out push
- - uses: actions/checkout@v3
- # Install Rust
- - uses: dtolnay/rust-toolchain@stable
- # Generate IOTypes.java
- - name: Run gen_io_types
- working-directory: gen_io_types
- run: cargo run
- - name: Install openjdk17
- run: sudo apt-get install openjdk-17-jdk
- # Grant execute permission for gradlew
- - name: Grant execute permission for gradlew
- run: chmod +x gradlew
- # Runs a single command using the runners shell
- - name: Compile and run tests on robot code
- run: ./gradlew build
- # Commit and push new type
- - name: Commit IOTypes
- run: |
- git config --global user.name 'Action'
- git config --global user.email 'wilsonwatson@users.noreply.github.com'
- git add -f src/main/java/org/frc5572/robotools/IOTypes.java
- git commit -m "Generate IOTypes.java" || true
- git push
linting:
name: Linting
runs-on: ubuntu-latest
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..0996538
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,73 @@
+{
+ "java.configuration.updateBuildConfiguration": "automatic",
+ "java.server.launchMode": "Standard",
+ "files.exclude": {
+ "**/.git": true,
+ "**/.svn": true,
+ "**/.hg": true,
+ "**/CVS": true,
+ "**/.DS_Store": true,
+ "bin/": true,
+ "**/.classpath": true,
+ "**/.project": true,
+ "**/.settings": true,
+ "**/.factorypath": true,
+ "**/*~": true
+ },
+ "java.test.config": [
+ {
+ "name": "WPIlibUnitTests",
+ "workingDirectory": "${workspaceFolder}/build/jni/release",
+ "vmargs": [
+ "-Djava.library.path=${workspaceFolder}/build/jni/release"
+ ],
+ "env": {
+ "LD_LIBRARY_PATH": "${workspaceFolder}/build/jni/release",
+ "DYLD_LIBRARY_PATH": "${workspaceFolder}/build/jni/release"
+ }
+ },
+ ],
+ "java.test.defaultConfig": "WPIlibUnitTests",
+ "java.format.settings.url": "formatter.xml",
+ "java.format.settings.profile": "GoogleStyle",
+ "[java]": {
+ "editor.defaultFormatter": "redhat.java",
+ },
+ "editor.codeActionsOnSave": {
+ "source.organizeImports": "explicit"
+ },
+ "editor.formatOnSave": true,
+ "editor.formatOnPaste": true,
+ "terminal.integrated.defaultProfile.windows": "Git Bash",
+ "java.import.gradle.annotationProcessing.enabled": false,
+ "java.completion.favoriteStaticMembers": [
+ "org.junit.Assert.*",
+ "org.junit.Assume.*",
+ "org.junit.jupiter.api.Assertions.*",
+ "org.junit.jupiter.api.Assumptions.*",
+ "org.junit.jupiter.api.DynamicContainer.*",
+ "org.junit.jupiter.api.DynamicTest.*",
+ "org.mockito.Mockito.*",
+ "org.mockito.ArgumentMatchers.*",
+ "org.mockito.Answers.*",
+ "edu.wpi.first.units.Units.*"
+ ],
+ "java.completion.filteredTypes": [
+ "java.awt.*",
+ "com.sun.*",
+ "sun.*",
+ "jdk.*",
+ "org.graalvm.*",
+ "io.micrometer.shaded.*",
+ "java.beans.*",
+ "java.util.Base64.*",
+ "java.util.Timer",
+ "java.sql.*",
+ "javax.swing.*",
+ "javax.management.*",
+ "javax.smartcardio.*",
+ "edu.wpi.first.math.proto.*",
+ "edu.wpi.first.math.**.proto.*",
+ "edu.wpi.first.math.**.struct.*",
+ ]
+}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index e1b779c..d870be0 100755
--- a/build.gradle
+++ b/build.gradle
@@ -4,19 +4,6 @@ plugins {
id 'maven-publish'
}
-tasks.withType(JavaCompile) {
- options.compilerArgs << '--add-exports' << 'jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED'
- options.compilerArgs << '--add-exports' << 'jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED'
- options.compilerArgs << '--add-exports' << 'jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED'
- options.compilerArgs << '--add-exports' << 'jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED'
- options.compilerArgs << '--add-exports' << 'jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED'
- options.compilerArgs << '--add-exports' << 'jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED'
- options.compilerArgs << '--add-exports' << 'jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED'
- options.compilerArgs << '--add-exports' << 'jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED'
- options.compilerArgs << '--add-exports' << 'jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED'
- options.compilerArgs << '--add-exports' << 'jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED'
-}
-
// sourceCompatibility = JavaVersion.VERSION_17
// targetCompatibility = JavaVersion.VERSION_17
@@ -25,7 +12,7 @@ repositories {
}
dependencies {
-
+ implementation "com.squareup:javapoet:1.13.0"
}
publishing {
@@ -34,7 +21,7 @@ publishing {
// Use jitpack format for publishing to mavenLocal
groupId = 'com.github.Frc5572'
artifactId = 'RobotTools'
- version = 'main-SNAPSHOT'
+ version = 'test-SNAPSHOT'
from components.java
}
diff --git a/checks.xml b/checks.xml
index f4f41c5..dc15ac8 100644
--- a/checks.xml
+++ b/checks.xml
@@ -42,7 +42,7 @@
-
+
diff --git a/gen_io_types/.gitignore b/gen_io_types/.gitignore
deleted file mode 100644
index 9c71cc9..0000000
--- a/gen_io_types/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/Cargo.lock
-/target
\ No newline at end of file
diff --git a/gen_io_types/Cargo.toml b/gen_io_types/Cargo.toml
deleted file mode 100644
index 6a12474..0000000
--- a/gen_io_types/Cargo.toml
+++ /dev/null
@@ -1,14 +0,0 @@
-[package]
-name = "gen_io_types"
-version = "0.1.0"
-edition = "2021"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-vendordeps = { git = "https://github.com/wilsonwatson/vendordeps.git" }
-binrw = "0.13"
-zip = "0.6"
-tokio = { version = "1", features = ["full"] }
-tempfile = "3.9"
-serde_json = "1"
\ No newline at end of file
diff --git a/gen_io_types/src/java.rs b/gen_io_types/src/java.rs
deleted file mode 100644
index 4866283..0000000
--- a/gen_io_types/src/java.rs
+++ /dev/null
@@ -1,192 +0,0 @@
-use binrw::BinRead;
-
-#[doc = "Enough of a Java Class to figure out its name, package and what it extends/implements"]
-#[binrw::binread]
-#[br(big, magic = b"\xca\xfe\xba\xbe")]
-pub struct MinimalJavaClass {
- #[br(temp)]
- _minor_version: u16,
- #[br(temp)]
- _major_version: u16,
- constant_pool: ConstantPool,
- access_flags: u16,
- this_class: u16,
- super_class: u16,
- #[br(temp)]
- interfaces_count: u16,
- #[br(count = interfaces_count)]
- _interfaces: Vec,
-}
-
-#[allow(unused)]
-impl MinimalJavaClass {
- pub fn this_class(&self) -> String {
- match &self.constant_pool.0[self.this_class as usize - 1] {
- ConstantPoolItem::Class { name_index } => {
- match &self.constant_pool.0[*name_index as usize - 1] {
- ConstantPoolItem::Utf8 { value } => {
- return value.clone();
- }
- x => panic!("cpool[this_class.name_index] is not a ConstantPoolItem::Utf8... Instead got {:?}", x)
- }
- },
- x => panic!("this_class is not a ConstantPoolItem::Class... Instead got {:?}", x)
- }
- }
-
- pub fn super_class(&self) -> String {
- match &self.constant_pool.0[self.super_class as usize - 1] {
- ConstantPoolItem::Class { name_index } => {
- match &self.constant_pool.0[*name_index as usize - 1] {
- ConstantPoolItem::Utf8 { value } => {
- return value.clone();
- }
- x => panic!("cpool[super_class.name_index] is not a ConstantPoolItem::Utf8... Instead got {:?}", x)
- }
- },
- x => panic!("super_class is not a ConstantPoolItem::Class... Instead got {:?}", x)
- }
- }
-
- pub fn is_public(&self) -> bool {
- (self.access_flags & 0x0001) != 0
- }
-
- pub fn is_interface(&self) -> bool {
- (self.access_flags & 0x0200) != 0
- }
-
- pub fn is_synthetic(&self) -> bool {
- (self.access_flags & 0x1000) != 0
- }
-
- pub fn is_annotation(&self) -> bool {
- (self.access_flags & 0x2000) != 0
- }
-
- pub fn is_enum(&self) -> bool {
- (self.access_flags & 0x4000) != 0
- }
-}
-
-struct ConstantPool(Vec);
-
-impl BinRead for ConstantPool {
- type Args<'a> = ();
-
- fn read_options(
- reader: &mut R,
- _endian: binrw::Endian,
- _args: Self::Args<'_>,
- ) -> binrw::prelude::BinResult {
- let cpool_count = u16::read_be(reader)?;
- let mut cpool = Vec::new();
- let mut i = 1;
- loop {
- if i >= cpool_count {
- break
- }
- let pos = reader.stream_position()?;
- let item = ConstantPoolItem::read_be(reader)?;
- let bump = match &item {
- ConstantPoolItem::Long { .. } | ConstantPoolItem::Double { .. } => 2,
- ConstantPoolItem::Skip => return Err(binrw::Error::AssertFail { pos, message: format!("Invalid Constant Pool Item.") }),
- _ => 1
- };
- cpool.push(item);
- for _ in 1..bump {
- cpool.push(ConstantPoolItem::Skip);
- }
-
- i += bump;
- }
- Ok(Self(cpool))
- }
-}
-
-#[doc = "Constant Pool Item enum. Defined in SE Spec sec 4.4"]
-#[binrw::binread]
-#[derive(Debug)]
-enum ConstantPoolItem {
- #[br(magic = 7u8)]
- Class {
- name_index: u16,
- },
- #[br(magic = 9u8)]
- Fieldref {
- _class_index: u16,
- _name_and_type_index: u16,
- },
- #[br(magic = 10u8)]
- Methodref {
- _class_index: u16,
- _name_and_type_index: u16,
- },
- #[br(magic = 11u8)]
- InterfaceMethodref {
- _class_index: u16,
- _name_and_type_index: u16,
- },
- #[br(magic = 8u8)]
- String {
- _string_index: u16,
- },
- #[br(magic = 3u8)]
- Integer {
- _bytes: u32,
- },
- #[br(magic = 4u8)]
- Float {
- _bytes: u32,
- },
- #[br(magic = 5u8)]
- Long {
- _bytes: u64,
- },
- #[br(magic = 6u8)]
- Double {
- _bytes: u64,
- },
- #[br(magic = 12u8)]
- NameAndType {
- _name_index: u16,
- _descriptor_index: u16,
- },
- #[br(magic = 1u8)]
- Utf8 {
- #[br(temp)]
- length: u16,
- // Technically, Java supports CESU-8, not UTF-8, but this is close enough for now.
- #[br(count = length, try_map = |x: Vec| String::from_utf8(x))]
- value: String,
- },
- #[br(magic = 15u8)]
- MethodHandle {
- _reference_kind: u8,
- _reference_index: u16,
- },
- #[br(magic = 16u8)]
- MethodType {
- _descriptor_index: u16,
- },
- #[br(magic = 17u8)]
- Dynamic {
- _bootstrap_method_attr_index: u16,
- _name_and_type_index: u16,
- },
- #[br(magic = 18u8)]
- InvokeDynamic {
- _bootstrap_method_attr_index: u16,
- _name_and_type_index: u16,
- },
- #[br(magic = 19u8)]
- Module {
- _name_index: u16,
- },
- #[br(magic = 20u8)]
- Package {
- _name_index: u16,
- },
-
- Skip,
-}
diff --git a/gen_io_types/src/main.rs b/gen_io_types/src/main.rs
deleted file mode 100644
index 8ba970d..0000000
--- a/gen_io_types/src/main.rs
+++ /dev/null
@@ -1,103 +0,0 @@
-use std::{collections::HashMap, io::{Read, Write}};
-
-use binrw::BinRead;
-use tempfile::tempdir;
-
-
-mod java;
-
-#[tokio::main]
-async fn main() {
- let source_dir = std::path::Path::new(file!()).canonicalize().unwrap();
- let source_dir = source_dir.parent().unwrap().parent().unwrap().parent().unwrap();
-
- let temp_dir = tempdir().unwrap();
-
- let mut interfaces = String::from("{");
- let mut classes = String::from("{");
-
- let wpi = std::fs::read(source_dir.join("config.json")).unwrap();
- let wpi: HashMap> = serde_json::from_slice(&wpi).unwrap();
- for interface in &wpi["interfaces"] {
- interfaces.push_str(&format!("\n {:?},", interface));
- }
- for class in &wpi["classes"] {
- classes.push_str(&format!("\n {:?},", class));
- }
-
- let skip = wpi["skip"].clone();
-
- let vendor_deps_dir = source_dir.join("vendordeps");
- for item in std::fs::read_dir(vendor_deps_dir).unwrap() {
- let item = item.unwrap();
- match item.path().extension().and_then(|x| x.to_str()) {
- Some("json") => {
- let vendordep: vendordeps::VendorDep = match serde_json::from_reader(std::fs::File::open(item.path()).unwrap()) {
- Ok(x) => x,
- Err(x) => {
- eprintln!("Invalid format for vendordep at {}", item.path().display());
- eprintln!("{}", x);
- continue
- },
- };
- vendordep.download_all_java_deps_to_folder(temp_dir.path()).await.unwrap();
- }
- _ => {}
- }
- }
-
- for item in std::fs::read_dir(temp_dir.path()).unwrap() {
- let item = item.unwrap();
- if item.file_type().unwrap().is_dir() {
- continue
- }
- let f = std::fs::File::open(item.path()).unwrap();
- let mut z = zip::ZipArchive::new(f).unwrap();
- for i in 0..z.len() {
- let mut f = z.by_index(i).unwrap();
- if !f.name().ends_with(".class") {
- continue
- }
- // ZipFile can't seek, so we need to fill it into a buffer first.
- let mut res = Vec::new();
- f.read_to_end(&mut res).unwrap();
-
- let mut res = std::io::Cursor::new(res);
- let class = java::MinimalJavaClass::read_be(&mut res).unwrap();
-
- if !class.is_public() {
- continue
- }
- if class.is_annotation() {
- continue
- }
- if class.is_enum() {
- continue
- }
-
- let name = class.this_class().replace('/', ".").replace('$', ".");
-
- if skip.contains(&name) {
- continue
- }
-
- if class.is_interface() {
- interfaces.push_str(&format!("\n {:?},", name));
- } else {
- classes.push_str(&format!("\n {:?},", name));
- }
- }
- }
-
- let mut outf = std::fs::File::create(source_dir.join("src/main/java/org/frc5572/robotools/IOTypes.java")).unwrap();
- writeln!(&mut outf, "package org.frc5572.robotools;\n").unwrap();
- writeln!(&mut outf, "/** Auto-generated list of IO interfaces and classes. */").unwrap();
- writeln!(&mut outf, "public class IOTypes {{\n").unwrap();
- writeln!(&mut outf, " /** List of interfaces disallowed a direct path to Robot.java. */").unwrap();
- writeln!(&mut outf, " public static String[] ioInterfaces = {}", interfaces).unwrap();
- writeln!(&mut outf, " }};").unwrap();
- writeln!(&mut outf, " /** List of classes disallowed a direct path to Robot.java. */").unwrap();
- writeln!(&mut outf, " public static String[] ioClasses = {}", classes).unwrap();
- writeln!(&mut outf, " }};").unwrap();
- writeln!(&mut outf, "}}\n").unwrap();
-}
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index c23a1b3..fe93de0 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=permwrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=permwrapper/dists
diff --git a/src/main/java/org/frc5572/robotools/AnnotationMirrorVisitor.java b/src/main/java/org/frc5572/robotools/AnnotationMirrorVisitor.java
new file mode 100644
index 0000000..1b8ff21
--- /dev/null
+++ b/src/main/java/org/frc5572/robotools/AnnotationMirrorVisitor.java
@@ -0,0 +1,27 @@
+package org.frc5572.robotools;
+
+import java.util.List;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.util.SimpleAnnotationValueVisitor8;
+
+/** Find all uses of an annotation in annotation values */
+public class AnnotationMirrorVisitor extends SimpleAnnotationValueVisitor8 {
+
+ @Override
+ public AnnotationMirror visitAnnotation(AnnotationMirror arg0, Void arg1) {
+ return arg0;
+ }
+
+ @Override
+ public AnnotationMirror visitArray(List extends AnnotationValue> arg0, Void arg1) {
+ for (var item : arg0) {
+ var res = this.visit(item, arg1);
+ if (res != null) {
+ return res;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/src/main/java/org/frc5572/robotools/Checks.java b/src/main/java/org/frc5572/robotools/Checks.java
deleted file mode 100644
index 1971cc8..0000000
--- a/src/main/java/org/frc5572/robotools/Checks.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.frc5572.robotools;
-
-import org.frc5572.robotools.checks.Check;
-import org.frc5572.robotools.checks.IOCheck;
-
-/** All checks to run. */
-public class Checks {
-
- private static final Check[] CHECKS = new Check[] {new IOCheck()};
-
- /** Run through all checks */
- public static boolean process(CompilationData data) {
- boolean fatal = false;
- for (Check c : CHECKS) {
- fatal = fatal || c.check(data);
- }
- return fatal;
- }
-
-}
diff --git a/src/main/java/org/frc5572/robotools/ClassListVisitor.java b/src/main/java/org/frc5572/robotools/ClassListVisitor.java
new file mode 100644
index 0000000..6b8e9c9
--- /dev/null
+++ b/src/main/java/org/frc5572/robotools/ClassListVisitor.java
@@ -0,0 +1,33 @@
+package org.frc5572.robotools;
+
+import java.util.List;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.SimpleAnnotationValueVisitor8;
+
+/** Find all uses of a type in annotation values */
+public class ClassListVisitor extends SimpleAnnotationValueVisitor8 {
+
+ private final List mirrors;
+
+ /** Find all uses of a type in annotation values */
+ public ClassListVisitor(List mirrors) {
+ super();
+ this.mirrors = mirrors;
+ }
+
+ @Override
+ public Void visitType(TypeMirror arg0, Void arg1) {
+ mirrors.add(arg0);
+ return null;
+ }
+
+ @Override
+ public Void visitArray(List extends AnnotationValue> arg0, Void arg1) {
+ for (var item : arg0) {
+ this.visit(item);
+ }
+ return null;
+ }
+
+}
diff --git a/src/main/java/org/frc5572/robotools/ClassVisitor.java b/src/main/java/org/frc5572/robotools/ClassVisitor.java
new file mode 100644
index 0000000..306aa03
--- /dev/null
+++ b/src/main/java/org/frc5572/robotools/ClassVisitor.java
@@ -0,0 +1,14 @@
+package org.frc5572.robotools;
+
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.SimpleAnnotationValueVisitor8;
+
+/** Find all uses of a type in annotation values */
+public class ClassVisitor extends SimpleAnnotationValueVisitor8 {
+
+ @Override
+ public TypeMirror visitType(TypeMirror arg0, Void arg1) {
+ return arg0;
+ }
+
+}
diff --git a/src/main/java/org/frc5572/robotools/CompilationData.java b/src/main/java/org/frc5572/robotools/CompilationData.java
deleted file mode 100755
index c7866ce..0000000
--- a/src/main/java/org/frc5572/robotools/CompilationData.java
+++ /dev/null
@@ -1,137 +0,0 @@
-package org.frc5572.robotools;
-
-import javax.annotation.processing.Messager;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.util.Types;
-import javax.tools.Diagnostic;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.LineMap;
-import com.sun.source.tree.Tree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TaskEvent;
-import com.sun.source.util.Trees;
-
-/**
- * Wrapper around a TypeElement. Includes helpers for printing errors, warnings etc.
- */
-public class CompilationData {
-
- /** Type Information for entire classpath. */
- public Types types;
- private Trees trees;
- private SourcePositions positions;
- private CompilationUnitTree compilationUnitTree;
- /** Element being processed */
- public TypeElement element;
- private Messager messager;
-
- /** Basic constructor. */
- public CompilationData(Types types, Trees trees, SourcePositions positions,
- CompilationUnitTree compilationUnitTree, TypeElement element, Messager messager) {
- this.types = types;
- this.trees = trees;
- this.positions = positions;
- this.compilationUnitTree = compilationUnitTree;
- this.element = element;
- this.messager = messager;
- }
-
- /** Constructor from Javac Plugin context. */
- public CompilationData(JavacTask task, TaskEvent event) {
- this(task.getTypes(), Trees.instance(task), Trees.instance(task).getSourcePositions(),
- event.getCompilationUnit(), event.getTypeElement(), null);
- }
-
- /** Constructor from Annotation Processor context. */
- public CompilationData(ProcessingEnvironment processingEnv, TypeElement element) {
- this(processingEnv.getTypeUtils(), null, null, null, element, processingEnv.getMessager());
- }
-
- /** Show error */
- public void error(Element element, Object object) {
- echo(element, object.toString(), Diagnostic.Kind.ERROR, "error", "Error");
- }
-
- /** Show warning */
- public void warn(Element element, Object object) {
- echo(element, object.toString(), Diagnostic.Kind.MANDATORY_WARNING, "warning", "Warning");
- }
-
- /** Show note (this doesn't work in VS Code yet) */
- public void note(Element element, Object object) {
- echo(element, object.toString(), Diagnostic.Kind.NOTE, "notice", "Note");
- }
-
- private void echo(Element element, String errString, Diagnostic.Kind kind, String ghString,
- String humanString) {
- if (compilationUnitTree == null) {
- messager.printMessage(kind, errString, element);
- } else {
- Tree tree = trees.getTree(element);
- LineMap linemap = compilationUnitTree.getLineMap();
- long pos = positions.getStartPosition(compilationUnitTree, tree);
- long row = linemap.getLineNumber(pos);
- String name = compilationUnitTree.getSourceFile().toUri().toString().split("/src/")[1];
- System.out
- .println("::" + ghString + " file=src/" + name + ",line=" + row + "::" + errString);
- }
- }
-
- private boolean _implements(String qualifiedName, TypeElement elem) {
- if (elem.getQualifiedName().toString().equals(qualifiedName)) {
- return true;
- }
- Element superClass = types.asElement(elem.getSuperclass());
- if (superClass instanceof TypeElement) {
- if (_implements(qualifiedName, (TypeElement) superClass)) {
- return true;
- }
- }
- for (var iface : elem.getInterfaces()) {
- Element interface_ = types.asElement(iface);
- if (interface_ instanceof TypeElement) {
- if (_implements(qualifiedName, (TypeElement) interface_)) {
- return true;
- }
- }
- }
- return false;
- }
-
- private boolean _extends(String qualifiedName, TypeElement elem) {
- if (elem.getQualifiedName().toString().equals(qualifiedName)) {
- return true;
- }
- Element superClass = types.asElement(elem.getSuperclass());
- if (superClass instanceof TypeElement) {
- if (_extends(qualifiedName, (TypeElement) superClass)) {
- return true;
- }
- }
- return false;
- }
-
- /** Get if this type implements an interface by name. */
- public boolean implementsInterface(String qualifiedName) {
- return _implements(qualifiedName, this.element);
- }
-
- /** Get if the specified type implements an interface by name. */
- public boolean implementsInterface(TypeElement e, String qualifiedName) {
- return _implements(qualifiedName, e);
- }
-
- /** Get if this type extends a class by name. */
- public boolean extendsClass(String qualifiedName) {
- return _extends(qualifiedName, this.element);
- }
-
- /** Get if the specified type extends a class by name. */
- public boolean extendsClass(TypeElement e, String qualifiedName) {
- return _extends(qualifiedName, e);
- }
-
-}
diff --git a/src/main/java/org/frc5572/robotools/IOTypes.java b/src/main/java/org/frc5572/robotools/IOTypes.java
deleted file mode 100644
index cc11c01..0000000
--- a/src/main/java/org/frc5572/robotools/IOTypes.java
+++ /dev/null
@@ -1,223 +0,0 @@
-package org.frc5572.robotools;
-
-/** Auto-generated list of IO interfaces and classes. */
-public class IOTypes {
-
- /** List of interfaces disallowed a direct path to Robot.java. */
- public static String[] ioInterfaces = {
- "edu.wpi.first.wpilibj.interfaces.Gyro",
- "edu.wpi.first.wpilibj.interfaces.Accelerometer",
- "edu.wpi.first.wpilibj.motorcontrol.MotorController",
- "com.revrobotics.SparkMaxPIDController",
- "com.revrobotics.CANSensor",
- "com.revrobotics.CANEncoder",
- "com.revrobotics.CANAnalog",
- "com.revrobotics.RelativeEncoder",
- "com.revrobotics.SparkMaxAbsoluteEncoder",
- "com.revrobotics.AbsoluteEncoder",
- "com.revrobotics.MotorFeedbackSensor",
- "com.revrobotics.CANPIDController",
- "com.revrobotics.SparkMaxLimitSwitch",
- "com.revrobotics.SparkMaxRelativeEncoder",
- "com.revrobotics.CANDigitalInput",
- "com.revrobotics.AnalogInput",
- "com.revrobotics.SparkMaxAnalogSensor",
- "com.ctre.phoenix6.ISerializable",
- "com.ctre.phoenix6.mechanisms.swerve.SwerveRequest",
- "com.ctre.phoenix6.hardware.ParentDevice.MapGenerator",
- "com.ctre.phoenix6.configs.ParentConfiguration",
- "com.kauailabs.navx.frc.ITimestampedDataSubscriber",
- };
- /** List of classes disallowed a direct path to Robot.java. */
- public static String[] ioClasses = {
- "edu.wpi.first.wpilibj.AnalogEncoder",
- "edu.wpi.first.wpilibj.AnalogGyro",
- "edu.wpi.first.wpilibj.AnalogInput",
- "edu.wpi.first.wpilibj.AnalogOutput",
- "edu.wpi.first.wpilibj.AnalogPotentiometer",
- "edu.wpi.first.wpilibj.AnalogTrigger",
- "edu.wpi.first.wpilibj.AnalogTriggerOutput",
- "edu.wpi.first.wpilibj.DMA",
- "edu.wpi.first.wpilibj.DigitalSource",
- "edu.wpi.first.wpilibj.DoubleSolenoid",
- "edu.wpi.first.wpilibj.Encoder",
- "edu.wpi.first.wpilibj.I2C",
- "edu.wpi.first.wpilibj.PWM",
- "edu.wpi.first.wpilibj.PneumaticsBase",
- "edu.wpi.first.wpilibj.PowerDistribution",
- "edu.wpi.first.wpilibj.Relay",
- "edu.wpi.first.wpilibj.SPI",
- "edu.wpi.first.wpilibj.SerialPort",
- "edu.wpi.first.wpilibj.Solenoid",
- "com.revrobotics.CANSparkBase.ExternalFollower",
- "com.revrobotics.ColorSensorV3",
- "com.revrobotics.jni.CANSparkMaxJNI",
- "com.revrobotics.jni.RevJNIWrapper",
- "com.revrobotics.jni.CANSWDLJNI",
- "com.revrobotics.SparkAbsoluteEncoder",
- "com.revrobotics.SparkFlexExternalEncoder",
- "com.revrobotics.ColorSensorV3.RawColor",
- "com.revrobotics.CANSparkMaxLowLevel.PeriodicStatus2",
- "com.revrobotics.SparkAnalogSensor",
- "com.revrobotics.CANSparkMaxLowLevel",
- "com.revrobotics.CIEColor",
- "com.revrobotics.SparkRelativeEncoder",
- "com.revrobotics.CANSparkLowLevel",
- "com.revrobotics.CANSparkFlex",
- "com.revrobotics.ColorMatchResult",
- "com.revrobotics.CANSparkMax",
- "com.revrobotics.SparkMaxAlternateEncoder",
- "com.revrobotics.CANSparkLowLevel.PeriodicStatus1",
- "com.revrobotics.CANSparkLowLevel.PeriodicStatus2",
- "com.revrobotics.CANSparkLowLevel.FollowConfig",
- "com.revrobotics.SparkLimitSwitch",
- "com.revrobotics.CANSparkMaxLowLevel.PeriodicStatus0",
- "com.revrobotics.ColorMatch",
- "com.revrobotics.SparkPIDController",
- "com.revrobotics.CANSparkLowLevel.FollowConfig.Config",
- "com.revrobotics.CANSparkLowLevel.PeriodicStatus0",
- "com.revrobotics.REVPhysicsSim",
- "com.revrobotics.CANSparkBase",
- "com.revrobotics.CANSparkMaxLowLevel.PeriodicStatus1",
- "com.revrobotics.DataPortConfigUtil",
- "com.ctre.phoenix6.Orchestra",
- "com.ctre.phoenix6.sim.TalonFXSimState",
- "com.ctre.phoenix6.sim.CANcoderSimState",
- "com.ctre.phoenix6.sim.Pigeon2SimState",
- "com.ctre.phoenix6.jni.ErrorReportingJNI",
- "com.ctre.phoenix6.jni.StatusSignalJNI",
- "com.ctre.phoenix6.jni.OrchestraJNI",
- "com.ctre.phoenix6.jni.CANBusJNI",
- "com.ctre.phoenix6.jni.SignalLoggerJNI",
- "com.ctre.phoenix6.jni.PlatformJNI",
- "com.ctre.phoenix6.jni.CtreJniWrapper",
- "com.ctre.phoenix6.wpiutils.AutoFeedEnable",
- "com.ctre.phoenix6.wpiutils.MotorSafetyImplem",
- "com.ctre.phoenix6.wpiutils.CallbackHelper",
- "com.ctre.phoenix6.SignalLogger",
- "com.ctre.phoenix6.Utils",
- "com.ctre.phoenix6.BaseStatusSignal",
- "com.ctre.phoenix6.controls.jni.ControlJNI",
- "com.ctre.phoenix6.controls.jni.ControlConfigJNI",
- "com.ctre.phoenix6.controls.compound.Diff_VelocityDutyCycle_Velocity",
- "com.ctre.phoenix6.controls.compound.Diff_MotionMagicTorqueCurrentFOC_Position",
- "com.ctre.phoenix6.controls.compound.Diff_VelocityDutyCycle_Position",
- "com.ctre.phoenix6.controls.compound.Diff_VelocityTorqueCurrentFOC_Velocity",
- "com.ctre.phoenix6.controls.compound.Diff_VelocityVoltage_Velocity",
- "com.ctre.phoenix6.controls.compound.Diff_PositionTorqueCurrentFOC_Velocity",
- "com.ctre.phoenix6.controls.compound.Diff_MotionMagicDutyCycle_Velocity",
- "com.ctre.phoenix6.controls.compound.Diff_DutyCycleOut_Velocity",
- "com.ctre.phoenix6.controls.compound.Diff_TorqueCurrentFOC_Velocity",
- "com.ctre.phoenix6.controls.compound.Diff_VoltageOut_Velocity",
- "com.ctre.phoenix6.controls.compound.Diff_PositionVoltage_Position",
- "com.ctre.phoenix6.controls.compound.Diff_PositionTorqueCurrentFOC_Position",
- "com.ctre.phoenix6.controls.compound.Diff_MotionMagicVoltage_Position",
- "com.ctre.phoenix6.controls.compound.Diff_PositionVoltage_Velocity",
- "com.ctre.phoenix6.controls.compound.Diff_VoltageOut_Position",
- "com.ctre.phoenix6.controls.compound.Diff_PositionDutyCycle_Velocity",
- "com.ctre.phoenix6.controls.compound.Diff_MotionMagicTorqueCurrentFOC_Velocity",
- "com.ctre.phoenix6.controls.compound.Diff_PositionDutyCycle_Position",
- "com.ctre.phoenix6.controls.compound.Diff_VelocityTorqueCurrentFOC_Position",
- "com.ctre.phoenix6.controls.compound.Diff_MotionMagicDutyCycle_Position",
- "com.ctre.phoenix6.controls.compound.Diff_VelocityVoltage_Position",
- "com.ctre.phoenix6.controls.compound.Diff_DutyCycleOut_Position",
- "com.ctre.phoenix6.controls.compound.Diff_TorqueCurrentFOC_Position",
- "com.ctre.phoenix6.controls.compound.Diff_MotionMagicVoltage_Velocity",
- "com.ctre.phoenix6.CANBus",
- "com.ctre.phoenix6.mechanisms.swerve.SwerveRequest.SwerveControlRequestParameters",
- "com.ctre.phoenix6.mechanisms.swerve.SwerveRequest.RobotCentric",
- "com.ctre.phoenix6.mechanisms.swerve.SwerveDrivetrain.OdometryThread",
- "com.ctre.phoenix6.mechanisms.swerve.SwerveRequest.SwerveDriveBrake",
- "com.ctre.phoenix6.mechanisms.swerve.SwerveRequest.ApplyChassisSpeeds",
- "com.ctre.phoenix6.mechanisms.swerve.SwerveDrivetrainConstants",
- "com.ctre.phoenix6.mechanisms.swerve.SwerveModuleConstants",
- "com.ctre.phoenix6.mechanisms.swerve.utility.PhoenixPIDController",
- "com.ctre.phoenix6.mechanisms.swerve.SwerveDrivetrain",
- "com.ctre.phoenix6.mechanisms.swerve.SwerveModule",
- "com.ctre.phoenix6.mechanisms.swerve.SwerveRequest.PointWheelsAt",
- "com.ctre.phoenix6.mechanisms.swerve.SimSwerveDrivetrain.SimSwerveModule",
- "com.ctre.phoenix6.mechanisms.swerve.SwerveModuleConstantsFactory",
- "com.ctre.phoenix6.mechanisms.swerve.SimSwerveDrivetrain",
- "com.ctre.phoenix6.mechanisms.swerve.SwerveRequest.FieldCentricFacingAngle",
- "com.ctre.phoenix6.mechanisms.swerve.SwerveRequest.FieldCentric",
- "com.ctre.phoenix6.mechanisms.swerve.SwerveDrivetrain.SwerveDriveState",
- "com.ctre.phoenix6.mechanisms.swerve.SwerveRequest.Idle",
- "com.ctre.phoenix6.mechanisms.DifferentialMechanism",
- "com.ctre.phoenix6.mechanisms.SimpleDifferentialMechanism",
- "com.ctre.phoenix6.StatusSignal.SignalMeasurement",
- "com.ctre.phoenix6.unmanaged.jni.UnmanagedJNI",
- "com.ctre.phoenix6.unmanaged.Unmanaged",
- "com.ctre.phoenix6.AllTimestamps",
- "com.ctre.phoenix6.StatusSignal",
- "com.ctre.phoenix6.hardware.CANcoder",
- "com.ctre.phoenix6.hardware.Pigeon2",
- "com.ctre.phoenix6.hardware.jni.HardwareJNI",
- "com.ctre.phoenix6.hardware.ParentDevice",
- "com.ctre.phoenix6.hardware.DeviceIdentifier",
- "com.ctre.phoenix6.hardware.core.CorePigeon2",
- "com.ctre.phoenix6.hardware.core.CoreTalonFX",
- "com.ctre.phoenix6.hardware.core.CoreCANcoder",
- "com.ctre.phoenix6.hardware.TalonFX",
- "com.ctre.phoenix6.CANBus.CANBusStatus",
- "com.ctre.phoenix6.Timestamp",
- "com.ctre.phoenix6.configs.CurrentLimitsConfigs",
- "com.ctre.phoenix6.configs.ClosedLoopGeneralConfigs",
- "com.ctre.phoenix6.configs.TalonFXConfiguration",
- "com.ctre.phoenix6.configs.DifferentialConstantsConfigs",
- "com.ctre.phoenix6.configs.AudioConfigs",
- "com.ctre.phoenix6.configs.VoltageConfigs",
- "com.ctre.phoenix6.configs.jni.ConfigJNI",
- "com.ctre.phoenix6.configs.SoftwareLimitSwitchConfigs",
- "com.ctre.phoenix6.configs.ParentConfigurator",
- "com.ctre.phoenix6.configs.MagnetSensorConfigs",
- "com.ctre.phoenix6.configs.CANcoderConfiguration",
- "com.ctre.phoenix6.configs.MotionMagicConfigs",
- "com.ctre.phoenix6.configs.SlotConfigs",
- "com.ctre.phoenix6.configs.ClosedLoopRampsConfigs",
- "com.ctre.phoenix6.configs.MountPoseConfigs",
- "com.ctre.phoenix6.configs.Pigeon2Configuration",
- "com.ctre.phoenix6.configs.MotorOutputConfigs",
- "com.ctre.phoenix6.configs.OpenLoopRampsConfigs",
- "com.ctre.phoenix6.configs.DifferentialSensorsConfigs",
- "com.ctre.phoenix6.configs.GyroTrimConfigs",
- "com.ctre.phoenix6.configs.Pigeon2FeaturesConfigs",
- "com.ctre.phoenix6.configs.TorqueCurrentConfigs",
- "com.ctre.phoenix6.configs.TalonFXConfigurator",
- "com.ctre.phoenix6.configs.Pigeon2Configurator",
- "com.ctre.phoenix6.configs.FeedbackConfigs",
- "com.ctre.phoenix6.configs.CANcoderConfigurator",
- "com.ctre.phoenix6.configs.Slot0Configs",
- "com.ctre.phoenix6.configs.CustomParamsConfigs",
- "com.ctre.phoenix6.configs.HardwareLimitSwitchConfigs",
- "com.ctre.phoenix6.configs.Slot1Configs",
- "com.ctre.phoenix6.configs.Slot2Configs",
- "com.kauailabs.vmx.AHRSJNI",
- "com.kauailabs.navx.AHRSProtocol.AHRSUpdate",
- "com.kauailabs.navx.IMUProtocol.YPRUpdate",
- "com.kauailabs.navx.AHRSProtocol.AHRSPosTSRawUpdate",
- "com.kauailabs.navx.IMUProtocol.GyroUpdate",
- "com.kauailabs.navx.frc.Tracer",
- "com.kauailabs.navx.frc.AHRS.BoardYawAxis",
- "com.kauailabs.navx.frc.IIOCompleteNotification.BoardState",
- "com.kauailabs.navx.frc.AHRS",
- "com.kauailabs.navx.frc.Quaternion",
- "com.kauailabs.navx.IMUProtocol.QuaternionUpdate",
- "com.kauailabs.navx.AHRSProtocol.AHRS_TUNING_VAR_ID",
- "com.kauailabs.navx.IMUProtocol.StreamCommand",
- "com.kauailabs.navx.AHRSProtocol.AHRSPosUpdate",
- "com.kauailabs.navx.AHRSProtocol.AHRS_DATA_TYPE",
- "com.kauailabs.navx.IMUProtocol",
- "com.kauailabs.navx.AHRSProtocol.AHRSPosTSUpdate",
- "com.kauailabs.navx.AHRSProtocol",
- "com.kauailabs.navx.AHRSProtocol.AHRS_DATA_ACTION",
- "com.kauailabs.navx.AHRSProtocol.MagCalData",
- "com.kauailabs.navx.AHRSProtocol.AHRSUpdateBase",
- "com.kauailabs.navx.AHRSProtocol.DataSetResponse",
- "com.kauailabs.navx.AHRSProtocol.IntegrationControl",
- "com.kauailabs.navx.IMURegisters",
- "com.kauailabs.navx.IMUProtocol.StreamResponse",
- "com.kauailabs.navx.AHRSProtocol.BoardID",
- "com.kauailabs.navx.AHRSProtocol.TuningVar",
- };
-}
-
diff --git a/src/main/java/org/frc5572/robotools/RobotPlugin.java b/src/main/java/org/frc5572/robotools/RobotPlugin.java
deleted file mode 100644
index 6b8a624..0000000
--- a/src/main/java/org/frc5572/robotools/RobotPlugin.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.frc5572.robotools;
-
-import javax.lang.model.util.Types;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.Plugin;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TaskEvent;
-import com.sun.source.util.TaskListener;
-import com.sun.source.util.Trees;
-
-/**
- * Javac plugin has source info, so it's used for Github Action annotations.
- */
-public class RobotPlugin implements Plugin {
-
- /**
- * Name used in build.gradle
- */
- @Override
- public String getName() {
- return "rchk";
- }
-
- /**
- * Function run when loaded
- */
- @Override
- public void init(JavacTask task, String... arg1) {
- Types types = task.getTypes();
- Trees trees = Trees.instance(task);
- SourcePositions positions = trees.getSourcePositions();
- task.addTaskListener(new TaskListener() {
- @Override
- public void finished(TaskEvent event) {
- if (event.getKind() == TaskEvent.Kind.ANALYZE) {
- CompilationData data = new CompilationData(types, trees, positions,
- event.getCompilationUnit(), event.getTypeElement(), null);
- Checks.process(data);
- }
- }
- });
- }
-
-}
diff --git a/src/main/java/org/frc5572/robotools/RobotProcessor.java b/src/main/java/org/frc5572/robotools/RobotProcessor.java
index 7eee768..9516e75 100644
--- a/src/main/java/org/frc5572/robotools/RobotProcessor.java
+++ b/src/main/java/org/frc5572/robotools/RobotProcessor.java
@@ -1,75 +1,235 @@
package org.frc5572.robotools;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
-import javax.annotation.processing.SupportedOptions;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
-import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeMirror;
+import javax.tools.Diagnostic;
+import javax.tools.Diagnostic.Kind;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterSpec;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
/**
* Annotation processor for checks. Used by VS Code.
*/
-@SupportedAnnotationTypes("*")
+@SupportedAnnotationTypes({"frc.robot.util.typestate.TypeStateBuilder",
+ "frc.robot.util.GenerateEmptyIO"})
@SupportedSourceVersion(SourceVersion.RELEASE_11)
-@SupportedOptions("frc_check.skip")
public class RobotProcessor extends AbstractProcessor {
- private boolean processTypeElement(TypeElement typeElement) {
- for (Element e3 : typeElement.getEnclosedElements()) {
- if (e3 instanceof TypeElement) {
- processTypeElement((TypeElement) e3);
- }
- }
- CompilationData data = new CompilationData(processingEnv, typeElement);
- return Checks.process(data);
- }
-
- private boolean hasProcessed;
-
/** Initialization function */
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
- hasProcessed = false;
}
/** Process all elements. */
@Override
- public boolean process(Set extends TypeElement> arg0, RoundEnvironment roundEnv) {
- if (hasProcessed) {
- return false;
+ public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ boolean success = false;
+ for (var anno : annotations) {
+ // System.out.println("Trying " + anno.getQualifiedName());
+ if (anno.getSimpleName().toString().equals("GenerateEmptyIO")) {
+ processGenerateEmptyIO(anno, roundEnv);
+ success = true;
+ } else if (anno.getSimpleName().toString().equals("TypeStateBuilder")) {
+ processGenerateTypeStateBuilder(anno, roundEnv);
+ success = true;
+ }
}
- hasProcessed = true;
- boolean fatal = false;
- for (ModuleElement mod : processingEnv.getElementUtils().getAllModuleElements()) {
- if (!mod.isUnnamed()) {
- continue;
+ return success;
+ }
+
+ private void processGenerateTypeStateBuilder(TypeElement annotation,
+ RoundEnvironment roundEnv) {
+ roundEnv.getElementsAnnotatedWith(annotation).forEach(constructorElement_ -> {
+ ExecutableElement constructorElement = (ExecutableElement) constructorElement_;
+ Element parent_ = constructorElement.getEnclosingElement();
+ if (!(parent_ instanceof TypeElement)) {
+ processingEnv.getMessager().printMessage(Kind.ERROR,
+ "TypeStateBuilder constructor must be the direct child of a TypeElement (e.g. class). Instead found "
+ + parent_.getKind().toString() + ".",
+ constructorElement);
}
- for (Element element : mod.getEnclosedElements()) {
- if (element instanceof PackageElement) {
- PackageElement packageElement = (PackageElement) element;
- if (packageElement.getQualifiedName().toString().startsWith("frc.")) {
- for (Element element2 : packageElement.getEnclosedElements()) {
- if (element2 instanceof TypeElement) {
- TypeElement typeElement = (TypeElement) element2;
- fatal = fatal || processTypeElement(typeElement);
- }
+ TypeElement parent = (TypeElement) parent_;
+ String builderName = parent.getSimpleName() + "Builder";
+ String builderPackage = getPackageName(parent);
+ // System.out.println("Processing " + builderPackage + "." + builderName);
+ for (var mirror : constructorElement.getAnnotationMirrors()) {
+ if (!mirror.getAnnotationType().asElement().getSimpleName().toString()
+ .equals("TypeStateBuilder")) {
+ continue;
+ }
+ for (var ev : mirror.getElementValues().entrySet()) {
+ if (ev.getKey().getSimpleName().toString().equals("value")) {
+ String res = ev.getValue().accept(new StringVisitor(), null);
+ if (res != null) {
+ builderName = res;
}
}
}
}
+
+ List fields = new ArrayList<>();
+ List extends VariableElement> params = constructorElement.getParameters();
+ for (int i = 0; i < params.size(); i++) {
+ boolean found = false;
+ VariableElement param = params.get(i);
+ for (var mirror : param.getAnnotationMirrors()) {
+ if (mirror.getAnnotationType().asElement().getSimpleName().toString()
+ .equals("InitField")) {
+ if (found) {
+ processingEnv.getMessager().printMessage(Kind.ERROR,
+ "Each parameter of a TypeStateBuilder constructor can only have one of @InitField, @RequiredField or @OptionalField",
+ param);
+ }
+ fields.add(new TypeStateBuilder.InitField(param.asType(),
+ param.getSimpleName().toString()));
+ found = true;
+ } else if (mirror.getAnnotationType().asElement().getSimpleName().toString()
+ .equals("RequiredField")) {
+ if (found) {
+ processingEnv.getMessager().printMessage(Kind.ERROR,
+ "Each parameter of a TypeStateBuilder constructor can only have one of @InitField, @RequiredField or @OptionalField",
+ param);
+ }
+ fields.add(TypeStateBuilder.RequiredField.fromAnnotation(param.asType(),
+ param.getSimpleName().toString(), mirror));
+ found = true;
+ } else if (mirror.getAnnotationType().asElement().getSimpleName().toString()
+ .equals("OptionalField")) {
+ if (found) {
+ processingEnv.getMessager().printMessage(Kind.ERROR,
+ "Each parameter of a TypeStateBuilder constructor can only have one of @InitField, @RequiredField or @OptionalField",
+ param);
+ }
+ fields.add(TypeStateBuilder.OptionalField.fromAnnotation(param.asType(),
+ param.getSimpleName().toString(), mirror));
+ found = true;
+ }
+ }
+ if (!found) {
+ processingEnv.getMessager().printMessage(Kind.ERROR,
+ "Each parameter of a TypeStateBuilder constructor must have one of @InitField, @RequiredField or @OptionalField",
+ param);
+ }
+ }
+
+ for (var field : fields) {
+ // System.out.println("field " + field.name);
+ if (field instanceof TypeStateBuilder.MethodField method_field) {
+ if (method_field.alt != null) {
+ // System.out.println(" alt");
+ }
+ }
+ }
+
+ var specBuilder =
+ TypeSpec.classBuilder(builderName).addModifiers(Modifier.PUBLIC, Modifier.FINAL);
+
+ TypeStateBuilder typeStateBuilder = new TypeStateBuilder(builderName,
+ fields.toArray(TypeStateBuilder.Field[]::new), parent.asType());
+ typeStateBuilder.apply(specBuilder);
+
+ var spec = specBuilder.build();
+
+ JavaFile file = JavaFile.builder(builderPackage, spec).build();
+ try {
+ file.writeTo(processingEnv.getFiler());
+ } catch (IOException e) {
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
+ "Failed to write class", constructorElement);
+ e.printStackTrace();
+ }
+ });
+ }
+
+ private void processGenerateEmptyIO(TypeElement annotation, RoundEnvironment roundEnv) {
+ roundEnv.getElementsAnnotatedWith(annotation).forEach(classElement_ -> {
+ TypeElement classElement = (TypeElement) classElement_;
+ String emptyClassName = classElement.getSimpleName() + "Empty";
+ String emptyPackage = getPackageName(classElement);
+
+ List params = new ArrayList<>();
+
+ for (var mirror : classElement.getAnnotationMirrors()) {
+ if (!mirror.getAnnotationType().asElement().getSimpleName().toString()
+ .equals("GenerateEmptyIO")) {
+ continue;
+ }
+ for (var ev : mirror.getElementValues().entrySet()) {
+ if (ev.getKey().getSimpleName().toString().equals("value")) {
+ ev.getValue().accept(new ClassListVisitor(params), null);
+ }
+ }
+ }
+
+ var specBuilder = TypeSpec.classBuilder(emptyClassName)
+ .addSuperinterface(TypeName.get(classElement.asType()))
+ .addModifiers(Modifier.PUBLIC, Modifier.FINAL);
+
+ AtomicInteger i = new AtomicInteger();
+ var constructor = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC)
+ .addParameters(params.stream().map(ty -> {
+ return ParameterSpec.builder(TypeName.get(ty), "arg" + i.incrementAndGet())
+ .build();
+ }).toList()).build();
+
+ for (var element : classElement.getEnclosedElements()) {
+ if (element instanceof ExecutableElement javaMethod) {
+ specBuilder
+ .addMethod(MethodSpec.methodBuilder(javaMethod.getSimpleName().toString())
+ .addModifiers(Modifier.PUBLIC).addAnnotation(Override.class)
+ .returns(TypeName.VOID)
+ .addParameters(javaMethod.getParameters().stream().map(param -> {
+ return ParameterSpec.builder(TypeName.get(param.asType()),
+ param.getSimpleName().toString()).build();
+ }).toList()).addCode("// Intentionally do nothing").build());
+ }
+ }
+
+ specBuilder = specBuilder.addMethod(constructor);
+
+ var spec = specBuilder.build();
+
+ JavaFile file = JavaFile.builder(emptyPackage, spec).build();
+ try {
+ file.writeTo(processingEnv.getFiler());
+ } catch (IOException e) {
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
+ "Failed to write class", classElement);
+ e.printStackTrace();
+ }
+ });
+ }
+
+ private static String getPackageName(Element e) {
+ while (e != null) {
+ if (e.getKind().equals(ElementKind.PACKAGE)) {
+ return ((PackageElement) e).getQualifiedName().toString();
+ }
+ e = e.getEnclosingElement();
}
- if (fatal) {
- throw new RuntimeException("Checks failed!");
- }
- return false;
+
+ return null;
}
}
diff --git a/src/main/java/org/frc5572/robotools/StringVisitor.java b/src/main/java/org/frc5572/robotools/StringVisitor.java
new file mode 100644
index 0000000..1b87b3c
--- /dev/null
+++ b/src/main/java/org/frc5572/robotools/StringVisitor.java
@@ -0,0 +1,13 @@
+package org.frc5572.robotools;
+
+import javax.lang.model.util.SimpleAnnotationValueVisitor8;
+
+/** Find all uses of a string in annotation values */
+public class StringVisitor extends SimpleAnnotationValueVisitor8 {
+
+ @Override
+ public String visitString(String arg0, Void arg1) {
+ return arg0;
+ }
+
+}
diff --git a/src/main/java/org/frc5572/robotools/TypeStateBuilder.java b/src/main/java/org/frc5572/robotools/TypeStateBuilder.java
new file mode 100644
index 0000000..e297119
--- /dev/null
+++ b/src/main/java/org/frc5572/robotools/TypeStateBuilder.java
@@ -0,0 +1,392 @@
+package org.frc5572.robotools;
+
+import java.util.Arrays;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.type.TypeMirror;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+
+/** Template builder for TypeState Builders */
+public class TypeStateBuilder {
+
+ private final Fields[] permutations;
+ private final int num_permutable_fields;
+
+ /** Template builder for TypeState Builders */
+ public TypeStateBuilder(String name, Field[] fields_, TypeMirror result) {
+ num_permutable_fields =
+ (int) Arrays.stream(fields_).filter((x) -> !(x instanceof InitField)).count();
+ permutations = new Fields[1 << num_permutable_fields];
+ boolean[] start = new boolean[num_permutable_fields];
+ Fields fields = new Fields(name, fields_, start, result);
+ while (true) {
+ int index = encodePermutationAsInt(start);
+ permutations[index] = fields;
+ start = Arrays.copyOf(start, start.length);
+ if (!advance(start)) {
+ break;
+ }
+ fields = new Fields(name, fields_, start, result);
+ }
+ }
+
+ /** Create typestate builders and write them to a typespec */
+ public void apply(TypeSpec.Builder builder) {
+ Fields base = permutations[encodePermutationAsInt(new boolean[num_permutable_fields])];
+ base.write_fields(builder);
+ base.write_constructor(builder, true);
+ base.write_methods(builder, permutations);
+ for (int i = 1; i < permutations.length; i++) {
+ if (permutations[i] == null) {
+ continue;
+ }
+ TypeSpec.Builder subBuilder = TypeSpec.classBuilder(permutations[i].class_name())
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL);
+ permutations[i].write_fields(subBuilder);
+ permutations[i].write_constructor(subBuilder, false);
+ permutations[i].write_methods(subBuilder, permutations);
+ builder.addType(subBuilder.build());
+ }
+ }
+
+ private static boolean advance(boolean[] permutation) {
+ for (int i = 0; i < permutation.length; i++) {
+ if (!permutation[i]) {
+ permutation[i] = true;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /** Base class for fields */
+ public static class Field {
+ /** Field type */
+ public final TypeMirror type;
+ /** Field name */
+ public final String name;
+
+ /** Base class for fields */
+ public Field(TypeMirror type, String name) {
+ this.type = type;
+ this.name = name;
+ }
+ }
+
+ /** Field that must be provided when creating a builder */
+ public static class InitField extends Field {
+ /** Field that must be provided when creating a builder */
+ public InitField(TypeMirror type, String name) {
+ super(type, name);
+ }
+ }
+
+ /** A non-init field */
+ public static class MethodField extends Field {
+ /** An alternative method for fulfilling this field. */
+ public final AltMethod alt;
+
+ /** A non-init field */
+ public MethodField(TypeMirror type, String name, AltMethod alt) {
+ super(type, name);
+ this.alt = alt;
+ }
+
+ /** A non-init field */
+ public MethodField(TypeMirror type, String name) {
+ this(type, name, null);
+ }
+ }
+
+ /** A field that is required to finish the builder. */
+ public static class RequiredField extends MethodField {
+
+ /** A field that is required to finish the builder. */
+ public RequiredField(TypeMirror type, String name, AltMethod alt) {
+ super(type, name, alt);
+ }
+
+ /** A field that is required to finish the builder. */
+ public RequiredField(TypeMirror type, String name) {
+ super(type, name);
+ }
+
+ /** A field that is required to finish the builder. */
+ public static RequiredField fromAnnotation(TypeMirror type, String name,
+ AnnotationMirror mirror) {
+ AltMethod alt = null;
+ for (var ev : mirror.getElementValues().entrySet()) {
+ if (ev.getKey().getSimpleName().toString().equals("alt")) {
+ AnnotationMirror altMirror =
+ ev.getValue().accept(new AnnotationMirrorVisitor(), null);
+ alt = AltMethod.fromAnnotation(altMirror, name);
+ }
+ }
+ return new RequiredField(type, name, alt);
+ }
+ }
+
+
+ /** A field that has a default in case it is not specified. */
+ public static class OptionalField extends MethodField {
+ /** Java expression that provides the default value. */
+ public final String default_code;
+
+ /** A field that has a default in case it is not specified. */
+ public OptionalField(TypeMirror type, String name, AltMethod alt, String default_code) {
+ super(type, name, alt);
+ this.default_code = default_code;
+ }
+
+ /** A field that has a default in case it is not specified. */
+ public OptionalField(TypeMirror type, String name, String default_code) {
+ super(type, name);
+ this.default_code = default_code;
+ }
+
+ /** A field that has a default in case it is not specified. */
+ public static OptionalField fromAnnotation(TypeMirror type, String name,
+ AnnotationMirror mirror) {
+ String defaultCode = "";
+ AltMethod alt = null;
+ for (var ev : mirror.getElementValues().entrySet()) {
+ if (ev.getKey().getSimpleName().toString().equals("value")) {
+ defaultCode = ev.getValue().accept(new StringVisitor(), null);
+ } else if (ev.getKey().getSimpleName().toString().equals("alt")) {
+ AnnotationMirror altMirror =
+ ev.getValue().accept(new AnnotationMirrorVisitor(), null);
+ alt = AltMethod.fromAnnotation(altMirror, name);
+ }
+ }
+ return new OptionalField(type, name, alt, defaultCode);
+ }
+ }
+
+ /** Alternative method for a field. */
+ public static record AltMethod(TypeMirror type, String parameterName, String code) {
+ /** Alternative method for a field. */
+ public static AltMethod fromAnnotation(AnnotationMirror mirror, String defaultName) {
+ if (mirror == null) {
+ System.out.println("annotation is null");
+ return null;
+ }
+
+ if (!mirror.getAnnotationType().asElement().getSimpleName().toString()
+ .equals("AltMethod")) {
+ System.out.println("annotation name doesn't match "
+ + mirror.getAnnotationType().asElement().getSimpleName().toString());
+ return null;
+ }
+ TypeMirror type = null;
+ String parameterName = defaultName;
+ String code = null;
+
+ for (var ev : mirror.getElementValues().entrySet()) {
+ if (ev.getKey().getSimpleName().toString().equals("type")) {
+ type = ev.getValue().accept(new ClassVisitor(), null);
+ } else if (ev.getKey().getSimpleName().toString().equals("parameter_name")) {
+ parameterName = ev.getValue().accept(new StringVisitor(), null);
+ } else if (ev.getKey().getSimpleName().toString().equals("value")) {
+ code = ev.getValue().accept(new StringVisitor(), null);
+ }
+ }
+
+ if (type == null) {
+ System.out.println("Missing type");
+ return null;
+ }
+ if (code == null) {
+ System.out.println("Missing code");
+ return null;
+ }
+
+ return new AltMethod(type, parameterName, code);
+ }
+ }
+
+
+ /** A specific permutation of fields. */
+ public static record Fields(String name, Field[] fields, boolean[] permutation,
+ TypeMirror result) {
+ /** A unique class name */
+ public String class_name() {
+ StringBuilder sb = new StringBuilder(name);
+ for (int i = 0; i < permutation.length; i++) {
+ sb.append(permutation[i] ? 1 : 0);
+ }
+ return sb.toString();
+ }
+
+ /** A unique class name */
+ public TypeName type_name() {
+ return ClassName.get("", class_name());
+ }
+
+ /** True if all required fields are filled. */
+ public boolean could_finish() {
+ int j = 0;
+ for (int i = 0; i < fields.length; i++) {
+ if (fields[i] instanceof MethodField) {
+ if (fields[i] instanceof RequiredField) {
+ if (!permutation[j]) {
+ return false;
+ }
+ }
+ j++;
+ }
+ }
+ return true;
+ }
+
+ /** True if all fields are filled. */
+ public boolean is_full() {
+ for (int i = 0; i < permutation.length; i++) {
+ if (!permutation[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /** Get the permutation if a given index is additionally filled. */
+ public boolean[] next_permutation(int index) {
+ boolean[] next_ = new boolean[permutation.length];
+ System.arraycopy(permutation, 0, next_, 0, permutation.length);
+ next_[index] = true;
+ return next_;
+ }
+
+ /** Write constructor to typespec builder */
+ public void write_constructor(TypeSpec.Builder builder, boolean is_public) {
+ var constructor = MethodSpec.constructorBuilder()
+ .addModifiers(is_public ? Modifier.PUBLIC : Modifier.PRIVATE);
+ int j = 0;
+ for (int i = 0; i < fields.length; i++) {
+ if (fields[i] instanceof MethodField) {
+ if (!permutation[j++]) {
+ continue;
+ }
+ }
+ constructor.addParameter(TypeName.get(this.fields[i].type),
+ this.fields[i].name + "_");
+ constructor
+ .addCode("this." + this.fields[i].name + "_ = " + this.fields[i].name + "_;\n");
+ }
+ builder.addMethod(constructor.build());
+ }
+
+ /** Write fields to typespec builder */
+ public void write_fields(TypeSpec.Builder builder) {
+ int j = 0;
+ for (int i = 0; i < fields.length; i++) {
+ if (fields[i] instanceof MethodField) {
+ if (!permutation[j++]) {
+ continue;
+ }
+ }
+ builder.addField(FieldSpec.builder(TypeName.get(fields[i].type),
+ fields[i].name + "_", Modifier.PRIVATE, Modifier.FINAL).build());
+ }
+ }
+
+ /** Write method to typespec builder */
+ private void write_method(TypeSpec.Builder builder, int index, MethodField field,
+ TypeName result) {
+ var method =
+ MethodSpec.methodBuilder(field.name).addModifiers(Modifier.PUBLIC, Modifier.FINAL)
+ .returns(result).addParameter(TypeName.get(field.type), field.name + "_");
+ method.addCode("return new $T(", result);
+ int j = 0;
+ boolean is_first = true;
+ for (int i = 0; i < fields.length; i++) {
+ if (i == index) {
+ if (!is_first) {
+ method.addCode(", ");
+ }
+ method.addCode(field.name + "_");
+ is_first = false;
+ }
+ if (fields[i] instanceof MethodField) {
+ if (!permutation[j++]) {
+ continue;
+ }
+ }
+ if (!is_first) {
+ method.addCode(", ");
+ }
+ method.addCode("this." + fields[i].name + "_");
+ is_first = false;
+ }
+ method.addCode(");");
+ builder.addMethod(method.build());
+ if (field.alt != null) {
+ method = MethodSpec.methodBuilder(field.name)
+ .addModifiers(Modifier.PUBLIC, Modifier.FINAL).returns(result)
+ .addParameter(TypeName.get(field.alt.type), field.alt.parameterName);
+ method.addCode("return this." + field.name + "(" + field.alt.code + ");");
+ builder.addMethod(method.build());
+ }
+ }
+
+ /** Write method to complete builder to typespec builder */
+ private void write_finish(TypeSpec.Builder builder) {
+ var method = MethodSpec.methodBuilder("finish")
+ .addModifiers(Modifier.PUBLIC, Modifier.FINAL).returns(TypeName.get(result));
+ method.addCode("return new $T(", TypeName.get(result));
+ int j = 0;
+ for (int i = 0; i < fields.length; i++) {
+ if (i != 0) {
+ method.addCode(", ");
+ }
+ if (fields[i] instanceof OptionalField optional_field) {
+ if (!permutation[j++]) {
+ method.addCode(optional_field.default_code);
+ continue;
+ }
+ }
+ if (fields[i] instanceof RequiredField) {
+ j++;
+ }
+ method.addCode("this." + fields[i].name + "_");
+ }
+ method.addCode(");");
+ builder.addMethod(method.build());
+ }
+
+ /** Write methods to advance builder to typespec builder */
+ public void write_methods(TypeSpec.Builder builder, Fields[] permutations) {
+ int j = 0;
+ for (int i = 0; i < this.fields.length; i++) {
+ if (fields[i] instanceof MethodField method_field) {
+ if (!permutation[j]) {
+ boolean[] next = next_permutation(j);
+ int next_index = encodePermutationAsInt(next);
+ TypeName result = permutations[next_index].type_name();
+ write_method(builder, i, method_field, result);
+ break;
+ }
+ j++;
+ }
+ }
+ if (could_finish()) {
+ write_finish(builder);
+ }
+ }
+ }
+
+ private static int encodePermutationAsInt(boolean[] permutation) {
+ int res = 0;
+ for (int i = 0; i < permutation.length; i++) {
+ if (permutation[i]) {
+ res += 1;
+ }
+ res <<= 1;
+ }
+ return res >> 1;
+ }
+
+}
diff --git a/src/main/java/org/frc5572/robotools/checks/Check.java b/src/main/java/org/frc5572/robotools/checks/Check.java
deleted file mode 100755
index 03a76dc..0000000
--- a/src/main/java/org/frc5572/robotools/checks/Check.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.frc5572.robotools.checks;
-
-import org.frc5572.robotools.CompilationData;
-
-/** A code checker */
-@FunctionalInterface
-public interface Check {
-
- /** Check if code is fine. Returns true if error is fatal. */
- public boolean check(CompilationData data);
-
-}
diff --git a/src/main/java/org/frc5572/robotools/checks/IOCheck.java b/src/main/java/org/frc5572/robotools/checks/IOCheck.java
deleted file mode 100755
index 001b780..0000000
--- a/src/main/java/org/frc5572/robotools/checks/IOCheck.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package org.frc5572.robotools.checks;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.ArrayType;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.SimpleAnnotationValueVisitor9;
-import org.frc5572.robotools.CompilationData;
-import org.frc5572.robotools.IOTypes;
-
-/** Performs checks to see that Subsystems do not contain raw IO types. */
-public class IOCheck implements Check {
-
- private void checkType(CompilationData data, Element[] warnPos, String path, TypeElement elem,
- Set skip, String post) {
- for (String iface : IOTypes.ioInterfaces) {
- if (data.implementsInterface(elem, iface)) {
- String[] parts = iface.split("\\.");
- for (Element warnElem : warnPos) {
-
- data.error(warnElem, path + " is a " + parts[parts.length - 1]
- + " which performs IO. It should be in an IO class!");
-
- }
- return;
- }
- }
- for (String class_ : IOTypes.ioClasses) {
- if (data.extendsClass(elem, class_)) {
- String[] parts = class_.split("\\.");
- for (Element warnElem : warnPos) {
-
- data.error(warnElem, path + " is a " + parts[parts.length - 1]
- + " which performs IO. It should be in an IO class!");
-
- }
- return;
- }
- }
- if (skip.contains(elem.getQualifiedName().toString())) {
- return;
- }
- skip.add(elem.getQualifiedName().toString());
- outer: for (var item : elem.getEnclosedElements()) {
- if (item instanceof VariableElement) {
- VariableElement variable = (VariableElement) item;
- for (AnnotationMirror mirror : item.getAnnotationMirrors()) {
- Element annotationElement = mirror.getAnnotationType().asElement();
- if (annotationElement instanceof TypeElement) {
- TypeElement annotationType = (TypeElement) annotationElement;
- if (annotationType.getQualifiedName().toString()
- .equals("java.lang.SuppressWarnings")) {
- for (var entry : mirror.getElementValues().entrySet()) {
- if (entry.getValue()
- .accept(new SimpleAnnotationValueVisitor9() {
-
- @Override
- public Boolean visitArray(
- List extends AnnotationValue> vals, Void p) {
- for (AnnotationValue v : vals) {
- if (v.accept(this, null)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public Boolean visitString(String s, Void p) {
- if (s.equals("IOCheck")) {
- return true;
- }
- return false;
- }
- }, null)) {
- continue outer;
- }
- }
- }
- }
- }
- String post2 = "";
- TypeMirror typeMirror = variable.asType();
- while (typeMirror instanceof ArrayType) {
- typeMirror = ((ArrayType) typeMirror).getComponentType();
- post2 += "[*]";
- }
- Element element = data.types.asElement(typeMirror);
- Element[] newElements = new Element[warnPos.length + 1];
- for (int i = 0; i < warnPos.length; i++) {
- newElements[i] = warnPos[i];
- }
- newElements[warnPos.length] = variable;
- if (element instanceof TypeElement) {
- TypeElement type = (TypeElement) element;
- checkType(data, newElements,
- path + post + "." + variable.getSimpleName().toString(), type, skip, post2);
- }
- }
- }
- }
-
- /** Perform check. */
- @Override
- public boolean check(CompilationData data) {
- if (data.implementsInterface("edu.wpi.first.wpilibj.RobotBase")) {
- for (var item : data.element.getEnclosedElements()) {
- if (item instanceof VariableElement) {
- VariableElement variable = (VariableElement) item;
- String path =
- data.element.getQualifiedName() + "." + variable.getSimpleName().toString();
- String post = "";
- TypeMirror typeMirror = variable.asType();
- while (typeMirror instanceof ArrayType) {
- typeMirror = ((ArrayType) typeMirror).getComponentType();
- post += "[*]";
- }
- Element element = data.types.asElement(typeMirror);
- if (element instanceof TypeElement) {
- TypeElement type = (TypeElement) element;
- Set skip = new HashSet<>();
- checkType(data, new Element[] {variable}, path, type, skip, post);
- }
- }
- }
- }
- return false;
- }
-
-}
diff --git a/src/main/resources/META-INF/services/com.sun.source.util.Plugin b/src/main/resources/META-INF/services/com.sun.source.util.Plugin
deleted file mode 100644
index 2057c50..0000000
--- a/src/main/resources/META-INF/services/com.sun.source.util.Plugin
+++ /dev/null
@@ -1 +0,0 @@
-org.frc5572.robotools.RobotPlugin
\ No newline at end of file
diff --git a/vendordeps/NavX.json b/vendordeps/NavX.json
deleted file mode 100644
index e978a5f..0000000
--- a/vendordeps/NavX.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "fileName": "NavX.json",
- "name": "NavX",
- "version": "2024.1.0",
- "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b",
- "frcYear": "2024",
- "mavenUrls": [
- "https://dev.studica.com/maven/release/2024/"
- ],
- "jsonUrl": "https://dev.studica.com/releases/2024/NavX.json",
- "javaDependencies": [
- {
- "groupId": "com.kauailabs.navx.frc",
- "artifactId": "navx-frc-java",
- "version": "2024.1.0"
- }
- ],
- "jniDependencies": [],
- "cppDependencies": [
- {
- "groupId": "com.kauailabs.navx.frc",
- "artifactId": "navx-frc-cpp",
- "version": "2024.1.0",
- "headerClassifier": "headers",
- "sourcesClassifier": "sources",
- "sharedLibrary": false,
- "libName": "navx_frc",
- "skipInvalidPlatforms": true,
- "binaryPlatforms": [
- "linuxathena",
- "linuxraspbian",
- "linuxarm32",
- "linuxarm64",
- "linuxx86-64",
- "osxuniversal",
- "windowsx86-64"
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/vendordeps/Phoenix6.json b/vendordeps/Phoenix6.json
deleted file mode 100644
index 69a4079..0000000
--- a/vendordeps/Phoenix6.json
+++ /dev/null
@@ -1,339 +0,0 @@
-{
- "fileName": "Phoenix6.json",
- "name": "CTRE-Phoenix (v6)",
- "version": "24.1.0",
- "frcYear": 2024,
- "uuid": "e995de00-2c64-4df5-8831-c1441420ff19",
- "mavenUrls": [
- "https://maven.ctr-electronics.com/release/"
- ],
- "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2024-latest.json",
- "conflictsWith": [
- {
- "uuid": "3fcf3402-e646-4fa6-971e-18afe8173b1a",
- "errorMessage": "The combined Phoenix-6-And-5 vendordep is no longer supported. Please remove the vendordep and instead add both the latest Phoenix 6 vendordep and Phoenix 5 vendordep.",
- "offlineFileName": "Phoenix6And5.json"
- }
- ],
- "javaDependencies": [
- {
- "groupId": "com.ctre.phoenix6",
- "artifactId": "wpiapi-java",
- "version": "24.1.0"
- }
- ],
- "jniDependencies": [
- {
- "groupId": "com.ctre.phoenix6",
- "artifactId": "tools",
- "version": "24.1.0",
- "isJar": false,
- "skipInvalidPlatforms": true,
- "validPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "linuxathena"
- ],
- "simMode": "hwsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "tools-sim",
- "version": "24.1.0",
- "isJar": false,
- "skipInvalidPlatforms": true,
- "validPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "simTalonSRX",
- "version": "24.1.0",
- "isJar": false,
- "skipInvalidPlatforms": true,
- "validPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "simTalonFX",
- "version": "24.1.0",
- "isJar": false,
- "skipInvalidPlatforms": true,
- "validPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "simVictorSPX",
- "version": "24.1.0",
- "isJar": false,
- "skipInvalidPlatforms": true,
- "validPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "simPigeonIMU",
- "version": "24.1.0",
- "isJar": false,
- "skipInvalidPlatforms": true,
- "validPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "simCANCoder",
- "version": "24.1.0",
- "isJar": false,
- "skipInvalidPlatforms": true,
- "validPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "simProTalonFX",
- "version": "24.1.0",
- "isJar": false,
- "skipInvalidPlatforms": true,
- "validPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "simProCANcoder",
- "version": "24.1.0",
- "isJar": false,
- "skipInvalidPlatforms": true,
- "validPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "simProPigeon2",
- "version": "24.1.0",
- "isJar": false,
- "skipInvalidPlatforms": true,
- "validPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- }
- ],
- "cppDependencies": [
- {
- "groupId": "com.ctre.phoenix6",
- "artifactId": "wpiapi-cpp",
- "version": "24.1.0",
- "libName": "CTRE_Phoenix6_WPI",
- "headerClassifier": "headers",
- "sharedLibrary": true,
- "skipInvalidPlatforms": true,
- "binaryPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "linuxathena"
- ],
- "simMode": "hwsim"
- },
- {
- "groupId": "com.ctre.phoenix6",
- "artifactId": "tools",
- "version": "24.1.0",
- "libName": "CTRE_PhoenixTools",
- "headerClassifier": "headers",
- "sharedLibrary": true,
- "skipInvalidPlatforms": true,
- "binaryPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "linuxathena"
- ],
- "simMode": "hwsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "wpiapi-cpp-sim",
- "version": "24.1.0",
- "libName": "CTRE_Phoenix6_WPISim",
- "headerClassifier": "headers",
- "sharedLibrary": true,
- "skipInvalidPlatforms": true,
- "binaryPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "tools-sim",
- "version": "24.1.0",
- "libName": "CTRE_PhoenixTools_Sim",
- "headerClassifier": "headers",
- "sharedLibrary": true,
- "skipInvalidPlatforms": true,
- "binaryPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "simTalonSRX",
- "version": "24.1.0",
- "libName": "CTRE_SimTalonSRX",
- "headerClassifier": "headers",
- "sharedLibrary": true,
- "skipInvalidPlatforms": true,
- "binaryPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "simTalonFX",
- "version": "24.1.0",
- "libName": "CTRE_SimTalonFX",
- "headerClassifier": "headers",
- "sharedLibrary": true,
- "skipInvalidPlatforms": true,
- "binaryPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "simVictorSPX",
- "version": "24.1.0",
- "libName": "CTRE_SimVictorSPX",
- "headerClassifier": "headers",
- "sharedLibrary": true,
- "skipInvalidPlatforms": true,
- "binaryPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "simPigeonIMU",
- "version": "24.1.0",
- "libName": "CTRE_SimPigeonIMU",
- "headerClassifier": "headers",
- "sharedLibrary": true,
- "skipInvalidPlatforms": true,
- "binaryPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "simCANCoder",
- "version": "24.1.0",
- "libName": "CTRE_SimCANCoder",
- "headerClassifier": "headers",
- "sharedLibrary": true,
- "skipInvalidPlatforms": true,
- "binaryPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "simProTalonFX",
- "version": "24.1.0",
- "libName": "CTRE_SimProTalonFX",
- "headerClassifier": "headers",
- "sharedLibrary": true,
- "skipInvalidPlatforms": true,
- "binaryPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "simProCANcoder",
- "version": "24.1.0",
- "libName": "CTRE_SimProCANcoder",
- "headerClassifier": "headers",
- "sharedLibrary": true,
- "skipInvalidPlatforms": true,
- "binaryPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- },
- {
- "groupId": "com.ctre.phoenix6.sim",
- "artifactId": "simProPigeon2",
- "version": "24.1.0",
- "libName": "CTRE_SimProPigeon2",
- "headerClassifier": "headers",
- "sharedLibrary": true,
- "skipInvalidPlatforms": true,
- "binaryPlatforms": [
- "windowsx86-64",
- "linuxx86-64",
- "osxuniversal"
- ],
- "simMode": "swsim"
- }
- ]
-}
\ No newline at end of file
diff --git a/vendordeps/REVLib.json b/vendordeps/REVLib.json
deleted file mode 100644
index 0f3520e..0000000
--- a/vendordeps/REVLib.json
+++ /dev/null
@@ -1,74 +0,0 @@
-{
- "fileName": "REVLib.json",
- "name": "REVLib",
- "version": "2024.2.0",
- "frcYear": "2024",
- "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb",
- "mavenUrls": [
- "https://maven.revrobotics.com/"
- ],
- "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2024.json",
- "javaDependencies": [
- {
- "groupId": "com.revrobotics.frc",
- "artifactId": "REVLib-java",
- "version": "2024.2.0"
- }
- ],
- "jniDependencies": [
- {
- "groupId": "com.revrobotics.frc",
- "artifactId": "REVLib-driver",
- "version": "2024.2.0",
- "skipInvalidPlatforms": true,
- "isJar": false,
- "validPlatforms": [
- "windowsx86-64",
- "windowsx86",
- "linuxarm64",
- "linuxx86-64",
- "linuxathena",
- "linuxarm32",
- "osxuniversal"
- ]
- }
- ],
- "cppDependencies": [
- {
- "groupId": "com.revrobotics.frc",
- "artifactId": "REVLib-cpp",
- "version": "2024.2.0",
- "libName": "REVLib",
- "headerClassifier": "headers",
- "sharedLibrary": false,
- "skipInvalidPlatforms": true,
- "binaryPlatforms": [
- "windowsx86-64",
- "windowsx86",
- "linuxarm64",
- "linuxx86-64",
- "linuxathena",
- "linuxarm32",
- "osxuniversal"
- ]
- },
- {
- "groupId": "com.revrobotics.frc",
- "artifactId": "REVLib-driver",
- "version": "2024.2.0",
- "libName": "REVLibDriver",
- "headerClassifier": "headers",
- "sharedLibrary": false,
- "skipInvalidPlatforms": true,
- "binaryPlatforms": [
- "windowsx86-64",
- "windowsx86",
- "linuxarm64",
- "linuxx86-64",
- "linuxathena",
- "linuxarm32",
- "osxuniversal"
- ]
- }
- ]
-}
\ No newline at end of file