Skip to content

Contributing

Yaroslav Sarchuk edited this page Aug 29, 2025 · 1 revision

Contributing Guide

Thank you for your interest in contributing to the Atomic Plugin! This guide will help you get started with contributing to the project.

🀝 Ways to Contribute

1. Report Bugs

  • Search existing issues first
  • Create detailed bug reports with reproduction steps
  • Include environment details (Rider version, OS, plugin version)

2. Suggest Features

  • Open a discussion first
  • Describe the use case and benefits
  • Provide examples of how it would work

3. Improve Documentation

  • Fix typos and grammar
  • Add examples and clarifications
  • Translate documentation
  • Create tutorials and guides

4. Submit Code

  • Fix bugs
  • Implement new features
  • Improve performance
  • Add tests

πŸš€ Getting Started

Prerequisites

  • JDK 17 or higher
  • Gradle 7.6 or higher
  • JetBrains Rider 2024.1 or higher
  • .NET SDK 6.0 or higher
  • Git
  • PowerShell (Windows) or Bash (macOS/Linux)

Development Setup

  1. Fork the Repository

    # Fork via GitHub UI, then clone
    git clone https://github.com/YOUR_USERNAME/atomic-rider-plugin.git
    cd atomic-rider-plugin
  2. Set Up Development Branch

    git checkout -b feature/your-feature-name
  3. Install Dependencies

    ./gradlew build
  4. Run Tests

    ./gradlew test
  5. Run Rider with Plugin

    ./gradlew runIde

πŸ“ Project Structure

atomic-rider-plugin/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ rider/                 # Kotlin/Java frontend (IntelliJ Platform)
β”‚   β”‚   └── main/
β”‚   β”‚       β”œβ”€β”€ kotlin/        # Plugin logic, PSI, actions
β”‚   β”‚       β”‚   └── com/jetbrains/rider/plugins/atomic/
β”‚   β”‚       β”‚       β”œβ”€β”€ language/      # Language support
β”‚   β”‚       β”‚       β”œβ”€β”€ actions/       # IDE actions
β”‚   β”‚       β”‚       β”œβ”€β”€ psi/          # PSI elements
β”‚   β”‚       β”‚       └── services/     # Services
β”‚   β”‚       └── resources/
β”‚   β”‚           └── META-INF/
β”‚   β”‚               └── plugin.xml    # Plugin configuration
β”‚   β”‚
β”‚   └── dotnet/                # C# backend (ReSharper)
β”‚       └── ReSharperPlugin.AtomicPlugin/
β”‚           β”œβ”€β”€ Services/      # Code generation services
β”‚           β”œβ”€β”€ Model/         # Data models
β”‚           └── Rider/         # Rider-specific components
β”‚
β”œβ”€β”€ protocol/                  # RD Protocol definitions
β”‚   └── src/main/kotlin/model/
β”‚
β”œβ”€β”€ gradle/                    # Gradle configuration
β”œβ”€β”€ build.gradle.kts          # Main build script
└── settings.gradle.kts       # Settings

πŸ’» Development Workflow

1. Language Support (Kotlin/Java)

Adding New Language Features

// src/rider/main/kotlin/.../language/AtomicAnnotator.kt
class AtomicAnnotator : Annotator {
    override fun annotate(element: PsiElement, holder: AnnotationHolder) {
        // Your annotation logic
        when (element) {
            is AtomicValueItem -> annotateValue(element, holder)
            is AtomicTagItem -> annotateTag(element, holder)
        }
    }
}

Creating Quick Fixes

class AddImportQuickFix(private val typeName: String) : LocalQuickFix {
    override fun getName() = "Import '$typeName'"
    
    override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
        val element = descriptor.psiElement
        val file = element.containingFile as? AtomicFile ?: return
        
        // Add import
        val import = AtomicPsiFactory.createImport(project, typeName)
        file.addImport(import)
    }
}

2. Code Generation (C#)

Modifying Generation Logic

// src/dotnet/.../Services/CodeGenerator.cs
public class CodeGenerator : ICodeGenerator
{
    public string GenerateExtensionMethods(EntityApiConfig config)
    {
        var sb = new StringBuilder();
        
        // Generate tags
        foreach (var tag in config.Tags)
        {
            sb.AppendLine(GenerateTagMethods(tag, config));
        }
        
        // Generate values
        foreach (var value in config.Values)
        {
            sb.AppendLine(GenerateValueMethods(value, config));
        }
        
        return sb.ToString();
    }
}

3. Protocol Communication

Adding Protocol Messages

// protocol/src/main/kotlin/model/AtomicGenerationModel.kt
object AtomicGenerationModel : Ext(Solution) {
    val generateCode = signal<GenerateCodeRequest, GenerateCodeResponse>()
    
    class GenerateCodeRequest(
        val filePath: String,
        val content: String
    )
    
    class GenerateCodeResponse(
        val success: Boolean,
        val generatedCode: String?,
        val error: String?
    )
}

πŸ§ͺ Testing

Unit Tests (Kotlin)

class AtomicParserTest {
    @Test
    fun `test parse simple atomic file`() {
        val content = """
            entityType: "IEntity"
            namespace: "Test"
            values:
                Health: int
        """.trimIndent()
        
        val file = createAtomicFile(content)
        val values = file.valuesSection?.valueItems
        
        assertEquals(1, values?.size)
        assertEquals("Health", values?.first()?.name)
        assertEquals("int", values?.first()?.type)
    }
}

Integration Tests (C#)

[TestFixture]
public class CodeGeneratorTests
{
    [Test]
    public void GeneratesCorrectGetterMethod()
    {
        var config = new EntityApiConfig
        {
            EntityType = "IEntity",
            Values = new Dictionary<string, string> { ["Health"] = "int" }
        };
        
        var generator = new CodeGenerator();
        var code = generator.GenerateExtensionMethods(config);
        
        Assert.That(code, Contains.Substring("GetHealth"));
        Assert.That(code, Contains.Substring("public static int"));
    }
}

πŸ“ Code Style

Kotlin Style Guide

  • Follow Kotlin Coding Conventions
  • Use 4 spaces for indentation
  • Maximum line length: 120 characters
  • Use meaningful variable names
// Good
val atomicFile = psiFile as? AtomicFile
val importsSection = atomicFile?.importsSection

// Bad
val f = psiFile as? AtomicFile
val is = f?.importsSection

C# Style Guide

  • Follow C# Coding Conventions
  • Use 4 spaces for indentation
  • Use PascalCase for public members
  • Use camelCase for private fields
// Good
public class EntityApiConfig
{
    private readonly string entityType;
    public string EntityType => entityType;
}

// Bad
public class entityapiconfig
{
    public string entity_type;
}

πŸ”„ Pull Request Process

1. Before Submitting

  • All tests pass (./gradlew test)
  • Code follows style guidelines
  • Documentation is updated
  • Commit messages are clear
  • Branch is up to date with main

2. PR Template

## Description
Brief description of changes

## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update

## Testing
- [ ] Unit tests pass
- [ ] Integration tests pass
- [ ] Manual testing completed

## Screenshots (if applicable)
Add screenshots here

## Checklist
- [ ] My code follows the project style
- [ ] I've added tests for my changes
- [ ] Documentation is updated
- [ ] All tests pass

3. Review Process

  1. Automated checks run (tests, linting)
  2. Code review by maintainers
  3. Address feedback
  4. Approval and merge

πŸ—οΈ Building and Packaging

Build Plugin

# Windows
.\buildPlugin.ps1

# macOS/Linux
./gradlew buildPlugin

Run All Tests

./gradlew test

Generate Documentation

./gradlew dokkaHtml

πŸ› Debugging

Debug in Rider

  1. Set breakpoints in your code
  2. Run with debug:
    ./gradlew runIde --debug-jvm
  3. Attach debugger in Rider

Enable Logging

import com.intellij.openapi.diagnostic.Logger

class MyClass {
    companion object {
        private val LOG = Logger.getInstance(MyClass::class.java)
    }
    
    fun myMethod() {
        LOG.debug("Debug message")
        LOG.info("Info message")
        LOG.error("Error message", exception)
    }
}

πŸ“š Resources

Documentation

Tools

🎯 Focus Areas

High Priority

  • Performance improvements
  • Bug fixes
  • Unity integration enhancements
  • Documentation improvements

Feature Requests

  • Multi-file generation
  • Template support
  • Better refactoring support
  • Advanced validation

πŸ“‹ Commit Guidelines

Commit Message Format

type(scope): subject

body

footer

Types

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation
  • style: Code style
  • refactor: Refactoring
  • perf: Performance
  • test: Tests
  • chore: Maintenance

Examples

feat(generation): add support for generic types

Add ability to use generic types in .atomic files.
Includes validation and proper code generation.

Closes #123
fix(parser): handle empty values section

Previously crashed when values section was empty.
Now generates valid code with no value methods.

Fixes #456

πŸ™ Recognition

Contributors are recognized in:

  • README.md contributors section
  • Release notes
  • GitHub contributors page

πŸ“¬ Contact

πŸ“„ License

By contributing, you agree that your contributions will be licensed under the MIT License.


Thank you for contributing to the Atomic Plugin! Your efforts help make this tool better for everyone.

Navigation

πŸ“š Documentation

πŸ“– Reference

❓ Help

πŸ”— Links

Clone this wiki locally