Skip to content

Commit 86ef8ae

Browse files
committed
Update build tools, platform version, and refactor CLAUDE.md
1 parent 70c7b38 commit 86ef8ae

12 files changed

Lines changed: 298 additions & 187 deletions

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
name: intellij-plugin-development
3+
description: IntelliJ plugin development reference when working on extension points, decompiling bundled plugin JARs, finding API usage examples, navigating IntelliJ SDK, or investigating how other plugins implement a feature.
4+
---
5+
6+
# IntelliJ Plugin Development
7+
8+
Quick reference for tools, APIs, and resources used when developing or investigating IntelliJ/PhpStorm plugins in this project.
9+
10+
---
11+
12+
## SDK & Documentation
13+
14+
- **SDK Docs:** https://plugins.jetbrains.com/docs/intellij/
15+
- **Extension Point List:** https://plugins.jetbrains.com/docs/intellij/extension-point-list.html
16+
- **IntelliJ Community Source:** https://github.com/JetBrains/intellij-community
17+
- **Plugin Template:** https://github.com/JetBrains/intellij-platform-plugin-template
18+
19+
---
20+
21+
## Skills in this folder
22+
23+
| File | Purpose |
24+
|---|---|
25+
| `references/extension-point-explorer.md` | Find plugins by extension point; search open-source implementations; download plugins for decompilation |
26+
| `references/decompilation.md` | Decompile plugin JARs with Vineflower; locate bundled JARs in Gradle cache; download ZIPs from Marketplace |
27+
28+
---
29+
30+
## Decompilation (quick reference)
31+
32+
Always use **Vineflower** — not IntelliJ's bundled Fernflower. A local copy is at `decompiled/vineflower.jar`.
33+
34+
```bash
35+
java -jar decompiled/vineflower.jar input.jar output-src/
36+
```
37+
38+
See [`references/decompilation.md`](./references/decompilation.md) for full usage, bundled JAR paths, and Marketplace ZIP downloads.
39+
40+
---
41+
42+
## Extension Point Explorer (quick reference)
43+
44+
Use the JetBrains Marketplace API to find plugins implementing a given extension point, get GitHub source search URLs or download plugin releases from the marketplace for decompilation.
45+
46+
See [`references/extension-point-explorer.md`](./references/extension-point-explorer.md) for step-by-step instructions.
47+
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Decompilation
2+
3+
Guide for decompiling IntelliJ plugin JARs to inspect features and implementation details.
4+
5+
---
6+
7+
## Vineflower (recommended)
8+
9+
Vineflower produces significantly better output than IntelliJ's bundled Fernflower. Always prefer it for decompiling plugin JARs.
10+
11+
- **GitHub:** https://github.com/Vineflower/vineflower
12+
- **Download:** https://repo1.maven.org/maven2/org/vineflower/vineflower/1.11.2/vineflower-1.11.2.jar
13+
- **Local copy in this project:** `decompiled/vineflower.jar`
14+
15+
```bash
16+
# Decompile a single JAR into a source directory
17+
java -jar decompiled/vineflower.jar input.jar output-src/
18+
19+
# Decompile all JARs in a directory
20+
java -jar decompiled/vineflower.jar input-dir/ output-src/
21+
```
22+
23+
---
24+
25+
## Bundled plugin JARs (IntelliJ/PhpStorm)
26+
27+
Gradle downloads plugin dependencies into the local cache. Typical path:
28+
29+
```
30+
~/.gradle/caches/<gradle-version>/transforms/*/transformed/<plugin-id>-<intellij-version>/<plugin>/lib/<plugin>.jar
31+
```
32+
33+
Examples:
34+
```bash
35+
# Twig plugin
36+
~/.gradle/caches/9.3.0/transforms/*/transformed/com.jetbrains.twig-253.28294.322/twig/lib/twig.jar
37+
38+
# PHP plugin
39+
~/.gradle/caches/9.3.0/transforms/*/transformed/com.jetbrains.php-253.*/php/lib/php.jar
40+
```
41+
42+
---
43+
44+
## Downloading a plugin JAR from the Marketplace
45+
46+
Use the JetBrains Marketplace API to fetch the latest release ZIP for any plugin ID (see `extension-point-explorer.md` for how to find plugin IDs):
47+
48+
```bash
49+
PLUGIN_ID="7219"
50+
51+
# Get the ZIP download path
52+
curl -s "https://plugins.jetbrains.com/api/plugins/${PLUGIN_ID}/updates?size=1" \
53+
| jq -r '"https://plugins.jetbrains.com/files/" + .[0].file'
54+
55+
# Download it directly
56+
FILE=$(curl -s "https://plugins.jetbrains.com/api/plugins/${PLUGIN_ID}/updates?size=1" | jq -r '.[0].file')
57+
curl -L -o plugin.zip "https://plugins.jetbrains.com/files/${FILE}"
58+
unzip plugin.zip -d plugin-src/
59+
```
60+
61+
Then decompile the extracted JAR:
62+
```bash
63+
java -jar decompiled/vineflower.jar plugin-src/lib/plugin.jar output-src/
64+
```
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# IntelliJ Extension Point Explorer
2+
3+
Use this skill to find plugins that implement a given IntelliJ extension point and to get GitHub source code search URLs for usage examples.
4+
5+
This skill also covers **downloading any plugin for decompilation and feature investigation** — see Section 3.
6+
7+
> **Important:** Extension point names are **case-sensitive** (e.g., `com.intellij.psi.referenceContributor``com.intellij.psi.ReferenceContributor`). Use the exact name as declared in `plugin.xml`.
8+
9+
---
10+
11+
## 1. Search for extension points by keyword
12+
13+
Before querying for plugins, find the **exact extension point name** by searching the JetBrains Marketplace extension point registry. Search is **case-insensitive** (the filtering is done client-side with `grep -i`), but the name you pass to Step 1 must be **exact and case-sensitive**.
14+
15+
```bash
16+
# Partial search — find all extension points containing a keyword
17+
KEYWORD="completion"
18+
19+
curl -s "https://plugins.jetbrains.com/api/extension-points" \
20+
| jq -r '.[].implementationName' \
21+
| grep -i "$KEYWORD" \
22+
| sort
23+
```
24+
25+
Examples:
26+
- `KEYWORD="contributor"` → lists all `*contributor*` extension points
27+
- `KEYWORD="completion.contributor"` → narrows to completion contributors
28+
- `KEYWORD="inspection"` → lists all inspection-related extension points
29+
30+
Once you have the exact name (e.g., `com.intellij.completion.contributor`), use it in Step 2.
31+
32+
---
33+
34+
## 2. Find plugins implementing an extension point
35+
36+
Query the JetBrains Plugin Repository GraphQL API to find open-source plugins that use a specific extension point:
37+
38+
```bash
39+
EXTENSION_POINT="com.intellij.psi.referenceContributor"
40+
41+
curl -s -X POST "https://plugins.jetbrains.com/api/search/graphql" \
42+
-H "Content-Type: application/json" \
43+
-d "{\"query\":\"{ plugins(search: { max: 24, offset: 0, filters: [{ field: \\\"fields.extensionPoints\\\", value: \\\"${EXTENSION_POINT}\\\" }, { field: \\\"hasSource\\\", value: \\\"true\\\" }, { field: \\\"family\\\", value: \\\"intellij\\\" }], sortBy: DOWNLOADS }) { total, plugins { id, name, downloads, sourceCodeUrl, lastUpdateDate, organization { id, verified } } } }\"}" \
44+
| jq -r --arg ep "$EXTENSION_POINT" '
45+
.data.plugins |
46+
"Total plugins found: \(.total)\n",
47+
(.plugins[] | select(.sourceCodeUrl != null and .sourceCodeUrl != "") |
48+
"Plugin: \(.name)",
49+
"ID: \(.id)",
50+
"Downloads: \(.downloads)",
51+
"Source: \(.sourceCodeUrl)",
52+
"Updated: \(.lastUpdateDate)",
53+
"Verified: \(.organization.verified // false)",
54+
"Marketplace: https://plugins.jetbrains.com/plugin/\(.id)",
55+
"Search: \("https://github.com/search?q=" + ("repo:" + (.sourceCodeUrl | ltrimstr("https://github.com/") | rtrimstr("/")) + " " + $ep | @uri) + "&type=code")",
56+
"---"
57+
)
58+
'
59+
```
60+
61+
## 3. Download a plugin for decompilation and feature investigation
62+
63+
> **Note:** This section is **not** limited to extension point research. Use it any time you want to download a plugin JAR/ZIP for decompilation, reverse engineering, or feature investigation — regardless of how you found the plugin ID.
64+
65+
The plugin ID can come from:
66+
- **Step 2** results (`ID: 7219`)
67+
- A Marketplace URL: `https://plugins.jetbrains.com/plugin/<ID>`
68+
69+
The `sourceCodeUrl` (GitHub URL) from Step 2 gives you two options:
70+
- **Search the repo** for usage examples → use the `Search:` URL from Step 2 output, or browse `https://github.com/<owner>/<repo>`
71+
- **Download the latest release** for decompilation → use the Marketplace API below to get the direct ZIP URL
72+
73+
Given a plugin ID, fetch its metadata and the direct ZIP download URL of the latest release:
74+
75+
```bash
76+
PLUGIN_ID="7219"
77+
78+
# Plugin metadata
79+
curl -s "https://plugins.jetbrains.com/api/plugins/${PLUGIN_ID}" \
80+
| jq '{
81+
id: .id,
82+
name: .name,
83+
xmlId: .xmlId,
84+
downloads: .downloads,
85+
source: .urls.sourceCodeUrl,
86+
marketplace: ("https://plugins.jetbrains.com/plugin/" + (.id | tostring))
87+
}'
88+
89+
# Latest release — includes direct ZIP download URL
90+
curl -s "https://plugins.jetbrains.com/api/plugins/${PLUGIN_ID}/updates?size=1" \
91+
| jq '.[0] | {
92+
version: .version,
93+
date: (.cdate | tonumber / 1000 | strftime("%Y-%m-%d")),
94+
downloads: .downloads,
95+
size_kb: (.size / 1024 | floor),
96+
channel: (if .channel == "" then "stable" else .channel end),
97+
download_url: ("https://plugins.jetbrains.com/files/" + .file),
98+
notes: (.notes | gsub("<[^>]+>"; "") | gsub("&gt;"; ">") | gsub("&lt;"; "<") | gsub("&amp;"; "&") | split("\n") | map(select(length > 0)) | .[:5] | join("\n"))
99+
}'
100+
```
101+
102+
Once you have the ZIP URL, download and decompile with **vineflower** (see [`references.md`](./references.md)):
103+
```bash
104+
curl -L -o plugin.zip "https://plugins.jetbrains.com/files/7219/974671/Symfony_Plugin-2026.1.289.zip"
105+
unzip plugin.zip -d plugin-extracted/
106+
java -jar decompiled/vineflower.jar plugin-extracted/lib/plugin.jar decompiled-src/
107+
```
108+
109+
---
110+
111+
## Notes
112+
113+
- **Case sensitivity:** `com.intellij.completion.contributor``com.intellij.CompletionContributor` — always verify the exact name in `plugin.xml` or IntelliJ SDK docs.
114+
- The API returns max 24 results per request; use `offset` to paginate.
115+
- `sortBy` options: `DOWNLOADS`, `UPDATE_DATE`, `RATING`.
116+
- Only plugins with `hasSource: true` and a non-empty `sourceCodeUrl` are useful for code examples.
117+
- `jq` and `curl` are required; `jq` must support `@uri` (version ≥ 1.6).
118+
- For decompilation tooling and API references, see [`references.md`](./references.md).

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,8 @@ out/
33
/php-annotation.jar
44
/build
55
/.gradle
6-
.intellijPlatform
6+
.intellijPlatform
7+
/decompiled
8+
/.junie
9+
*.hprof
10+
.mcp.json

AGENTS.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
This is an IntelliJ IDEA/PhpStorm plugin that provides PHP annotation and PHP 8 Attribute support. The plugin extends the IDE to recognize annotation classes marked with `@Annotation`, provides code completion, navigation, inspections, and integrates with Doctrine ORM and Symfony frameworks.
8+
9+
**Plugin ID**: `de.espend.idea.php.annotation`
10+
11+
## Build Commands
12+
13+
### Build the plugin
14+
```bash
15+
./gradlew buildPlugin
16+
```
17+
The plugin ZIP will be in `build/distributions/`.
18+
19+
### Running Tests
20+
21+
```bash
22+
# Run all tests
23+
./gradlew test
24+
25+
# Run a specific test class
26+
./gradlew test --tests "fr.adrienbrault.idea.symfony2plugin.tests.dic.SymfonyContainerTypeProviderTest"
27+
28+
# Run tests matching a pattern
29+
./gradlew test --tests "*ContainerTest"
30+
```
31+
32+
## Architecture
33+
34+
- Tests extend `AnnotationLightCodeInsightFixtureTestCase` which provides a test fixture framework.
35+
36+
Test data files are in `src/test/java/de/espend/idea/php/annotation/tests/fixtures/`.
37+
38+
39+
## Decompiler Tools
40+
41+
For analyzing bundled plugins like Twig and PHP you MUST use **vineflower** and NOT **Fernflower** from IntelliJ (less quality):
42+
43+
**vineflower**
44+
45+
- **GitHub:** https://github.com/Vineflower/vineflower
46+
- **Download:** https://repo1.maven.org/maven2/org/vineflower/vineflower/1.11.2/vineflower-1.11.2.jar
47+
- **Local copy:** `decompiled/vineflower.jar`
48+
- **Usage:** `java -jar vineflower.jar input.jar output/`
49+
50+
**Bundled Plugin JARs (for decompilation):**
51+
- **Location:** `~/.gradle/caches/[gradle-version]/transforms/*/transformed/com.jetbrains.[plugin]-[intellij-version]/[plugin]/lib/[plugin].jar`
52+
- **Example:** `~/.gradle/caches/9.3.0/transforms/*/transformed/com.jetbrains.twig-253.28294.322/twig/lib/twig.jar`

0 commit comments

Comments
 (0)