mirror of
https://github.com/JetBrains/intellij-sdk-code-samples.git
synced 2025-07-29 17:57:53 +08:00
Merge branch 'master' of https://github.com/JetBrains/intellij-sdk-docs
This commit is contained in:
commit
628888d2a3
@ -7,7 +7,7 @@ Thanks for contributing! Here are few useful things to know before submitting yo
|
||||
* Licensing - see [LICENSE.txt](LICENSE.txt)
|
||||
* [Setting up your environment](#setting-up-your-environment)
|
||||
* [Markup](#markup)
|
||||
* _SUMMARY.md
|
||||
* [_SUMMARY.md](#summarymd)
|
||||
* [Redirects](#redirects)
|
||||
* [Table of contents](#table-of-contents)
|
||||
* [Liquid tags and filters](#liquid-tags-and-filters)
|
||||
|
@ -88,7 +88,10 @@
|
||||
* [Editor Components](user_interface_components/editor_components.md)
|
||||
* [List and Tree Controls](user_interface_components/lists_and_trees.md)
|
||||
* [Miscellaneous Swing Components](user_interface_components/misc_swing_components.md)
|
||||
* PHPStorm and WebStorm
|
||||
* [PHPStorm](storm/phpstorm.md)
|
||||
* [Setting-up the environment](storm/setting_up_environment.md)
|
||||
* [PHP Open API](storm/php_open_api.md)
|
||||
* [Existing 3rd party plugins](storm/existing_plugins.md)
|
||||
* [Tutorials](tutorials.md)
|
||||
* [Custom Language Support](tutorials/custom_language_support_tutorial.md)
|
||||
* [1. Prerequisites](tutorials/custom_language_support/prerequisites.md)
|
||||
|
35
storm/existing_plugins.md
Normal file
35
storm/existing_plugins.md
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
title: Existing 3rd party framework-specific plugins
|
||||
---
|
||||
|
||||
## Magicento
|
||||
|
||||
Magicento is a free PHPStorm plugin for Magento developers.
|
||||
Features include: Goto for factories and template paths, autocomplete for factories, xml files and class names, documentation for xml nodes, evaluation of PHP code inside Magento environment, and much more to come!
|
||||
|
||||
* [Official Magicento Web Site](http://magicento.com/)
|
||||
* [GitHub](https://github.com/enriquepiatti/Magicento)
|
||||
* [Magicento in PhpStorm Plugins Repository](http://plugins.jetbrains.com/plugin/?webide&pluginId=7089)
|
||||
|
||||
## YiiStorm
|
||||
|
||||
YiiStorm is a plugin for PhpStorm IDE that is adding code navigation enhancements for Yii framework based projects.
|
||||
Features are: Going from render and renderPartial to the view file. Includes controllers, partials and widgets. Supports all ways of specifying a view: themes, smarty .tpl views and external actions; Going from model name in relations() to the model class; Going from the $this->widget('path.to.widget.Class') call to the widget class; Going from controller actions() to action class.
|
||||
|
||||
* [Official YiiStorm Web Site](http://mazx.ru/)
|
||||
* [GitHub](https://github.com/cmazx/yiistorm)
|
||||
* [YiiStorm in PhpStorm Plugins Repository](https://plugins.jetbrains.com/plugin/?webide&pluginId=7182)
|
||||
|
||||
## Symfony2 - Clickable Views
|
||||
|
||||
Symfony2 - Clickable Views is a plugin for Symfony2 Framework developers. Resolves on CTRL+Click the corresponding twig template in your Symfony2 project. This plugin demands a projectstructure which you can find in the Symfony2 Std. Edition and will not work with custom layouts.
|
||||
|
||||
* [GitHub](https://github.com/xenji/phpstorm-symfony2-plugin)
|
||||
* [Symfony2 - Clickable Views plugin in PhpStorm Plugins Repository](https://plugins.jetbrains.com/plugin?pr=webide&pluginId=7057)
|
||||
|
||||
## Symfony2 - Factory Support
|
||||
|
||||
Symfony2 - Clickable Views is a plugin for Symfony2 Framework developers. Resolves on CTRL+Click the corresponding twig template in your Symfony2 project. This plugin demands a projectstructure which you can find in the Symfony2 Std. Edition and will not work with custom layouts.
|
||||
|
||||
* [GitHub](https://github.com/Haehnchen/idea-php-symfony2-plugin)
|
||||
* [Symfony2 plugin in PhpStorm Plugins Repository](https://plugins.jetbrains.com/plugin?pr=&pluginId=7219)
|
BIN
storm/img/AddingLibrary.png
Normal file
BIN
storm/img/AddingLibrary.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 73 KiB |
BIN
storm/img/changingscope.png
Normal file
BIN
storm/img/changingscope.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
212
storm/php_open_api.md
Normal file
212
storm/php_open_api.md
Normal file
@ -0,0 +1,212 @@
|
||||
---
|
||||
title: PHP Open API
|
||||
---
|
||||
|
||||
## Using php-openapi
|
||||
|
||||
```xml
|
||||
<depends>com.jetbrains.php</depends>
|
||||
```
|
||||
|
||||
## PHP PSI
|
||||
|
||||
`com.jetbrains.php.lang.psi.elements.*;`
|
||||
|
||||
## Utility Classes
|
||||
|
||||
## PHP Extension Points
|
||||
|
||||
### PhpTypeProvider
|
||||
|
||||
Here is a code fragment that makes [generic Factory Method support](https://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Advanced+Metadata#PhpStormAdvancedMetadata-Factorymethods) work
|
||||
|
||||
```xml
|
||||
<php.typeProvider2 implementation="com.jetbrains.php.lang.psi.resolve.types.PhpStaticFactoryTypeProvider2"/>
|
||||
```
|
||||
|
||||
Interface:
|
||||
|
||||
```java
|
||||
/**
|
||||
* Extension point to implement to provide Type information on various PhpPsiElements
|
||||
*/
|
||||
public interface PhpTypeProvider2 {
|
||||
|
||||
ExtensionPointName<PhpTypeProvider2> EP_NAME = ExtensionPointName.create("com.intellij.php.typeProvider2");
|
||||
|
||||
/**
|
||||
* @return Your custom signature key, i.e. "?". Do not use any of PhpTypeSignatureKey.XXX constants though!
|
||||
*/
|
||||
char getKey();
|
||||
|
||||
/**
|
||||
* @param element to deduce type for - using only LOCAL info. <b>THIS IS MOST CRUCIAL ASPECT TO FOLLOW</b>
|
||||
* @return type for element, null if no insight. You can return a custom signature here to be later decoded by method below.
|
||||
*/
|
||||
@Nullable
|
||||
String getType(PsiElement element);
|
||||
|
||||
/**
|
||||
* @param expression Signature expression to decode. You can use PhpIndex.getBySignature() to look up expression internals.
|
||||
* @param project well so you can reach the PhpIndex
|
||||
* @return null if no match
|
||||
*/
|
||||
Collection<? extends PhpNamedElement> getBySignature(String expression, Project project);
|
||||
}
|
||||
```
|
||||
|
||||
Our implementation: includes a Completion contributor for the parameter values too.
|
||||
|
||||
```java
|
||||
/**
|
||||
*/
|
||||
public class PhpStaticFactoryTypeProvider extends CompletionContributor implements PhpTypeProvider2 {
|
||||
|
||||
private static final Key<CachedValue<Map<String, Map<String, String>>>> STATIC_FACTORY_TYPE_MAP =
|
||||
new Key<CachedValue<Map<String, Map<String, String>>>>("STATIC_FACTORY_TYPE_MAP");
|
||||
|
||||
@Override
|
||||
public char getKey() {
|
||||
return 'S';
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getType(PsiElement e) {
|
||||
if (e instanceof MethodReference && ((MethodReference)e).isStatic()) {
|
||||
Map<String, Map<String, String>> methods = getStaticMethodTypesMap(e.getProject());
|
||||
String refSignature = ((MethodReference)e).getSignature();
|
||||
if (methods.containsKey(refSignature)) {
|
||||
PsiElement[] parameters = ((MethodReference)e).getParameters();
|
||||
if (parameters.length > 0) {
|
||||
PsiElement parameter = parameters[0];
|
||||
if (parameter instanceof StringLiteralExpression) {
|
||||
String param = ((StringLiteralExpression)parameter).getContents();
|
||||
if (StringUtil.isNotEmpty(param)) return refSignature + "." + param;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends PhpNamedElement> getBySignature(String expression, Project project) {
|
||||
Map<String, Map<String, String>> methods = getStaticMethodTypesMap(project);
|
||||
int dot = expression.lastIndexOf('.');
|
||||
String refSignature = expression.substring(0, dot);
|
||||
Map<String, String> types = methods.get(refSignature);
|
||||
if (types != null) {
|
||||
String type = types.get(expression.substring(dot + 1));
|
||||
if (type != null) return PhpIndex.getInstance(project).getAnyByFQN(type);
|
||||
}
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
synchronized Map<String, Map<String, String>> getStaticMethodTypesMap(final Project project) {
|
||||
CachedValue<Map<String, Map<String, String>>> myStaticMethodTypesMap = project.getUserData(STATIC_FACTORY_TYPE_MAP);
|
||||
if (myStaticMethodTypesMap == null) {
|
||||
myStaticMethodTypesMap = CachedValuesManager.getManager(project).createCachedValue(
|
||||
new CachedValueProvider<Map<String, Map<String, String>>>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Result<Map<String, Map<String, String>>> compute() {
|
||||
Map<String, Map<String, String>> map = new THashMap<String, Map<String, String>>();
|
||||
Collection<Variable> variables = getVariables(project, "STATIC_METHOD_TYPES");
|
||||
for (Variable variable : variables) {
|
||||
if (!"\\PHPSTORM_META\\".equals(variable.getNamespaceName())) continue;
|
||||
PsiElement parent = variable.getParent();
|
||||
if (parent instanceof AssignmentExpression) {
|
||||
PhpPsiElement value = ((AssignmentExpression)parent).getValue();
|
||||
if (value instanceof ArrayCreationExpression) {
|
||||
for (ArrayHashElement element : ((ArrayCreationExpression)value).getHashElements()) {
|
||||
PhpPsiElement match = element.getKey();
|
||||
if (match instanceof MethodReference) {
|
||||
String matchSignature = ((MethodReference)match).getSignature();
|
||||
Map<String, String> types = map.get(matchSignature);
|
||||
if (types == null) {
|
||||
types = new THashMap<String, String>();
|
||||
map.put(matchSignature, types);
|
||||
}
|
||||
PhpPsiElement val = element.getValue();
|
||||
if (val instanceof ArrayCreationExpression) {
|
||||
PhpPsiElement child = val.getFirstPsiChild();
|
||||
while (child != null) {
|
||||
if (child.getFirstPsiChild() instanceof BinaryExpression) {
|
||||
BinaryExpression binary = ((BinaryExpression)child.getFirstPsiChild());
|
||||
if (binary.getOperation().getNode().getElementType() == PhpTokenTypes.kwINSTANCEOF) {
|
||||
PsiElement leftOperand = binary.getLeftOperand();
|
||||
PsiElement rightOperand = binary.getRightOperand();
|
||||
if (leftOperand instanceof StringLiteralExpression && rightOperand != null) {
|
||||
types.put(((StringLiteralExpression)leftOperand).getContents(), rightOperand.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
child = child.getNextPsiSibling();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return CachedValueProvider.Result.create(map, getMetaFile(project));
|
||||
}
|
||||
}, false);
|
||||
project.putUserData(STATIC_FACTORY_TYPE_MAP, myStaticMethodTypesMap);
|
||||
}
|
||||
return myStaticMethodTypesMap.getValue();
|
||||
}
|
||||
|
||||
private static Collection<Variable> getVariables(Project project, final String key) {
|
||||
PsiFile file = getMetaFile(project);
|
||||
final Collection<Variable> result = new SmartList<Variable>();
|
||||
if (file instanceof PhpFile) {
|
||||
//AG not the most elegant way - but still an allowed usage.
|
||||
//noinspection deprecation
|
||||
file.accept(new PhpRecursiveElementVisitor() {
|
||||
@Override
|
||||
public void visitPhpAssignmentExpression(AssignmentExpression assignmentExpression) {
|
||||
PhpPsiElement variable = assignmentExpression.getVariable();
|
||||
if (variable instanceof Variable) {
|
||||
if (((Variable)variable).getNameCS().equals(key)) {
|
||||
result.add((Variable)variable);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static PsiFile getMetaFile(Project project) {
|
||||
VirtualFile metaFile = LocalFileSystem.getInstance().findFileByPath(project.getBasePath() + File.separatorChar + ".phpstorm.meta.php");
|
||||
return metaFile != null ? PsiManager.getInstance(project).findFile(metaFile) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
|
||||
final ProcessingContext context = new ProcessingContext();
|
||||
PsiElement position = parameters.getPosition();
|
||||
if (parameters.getCompletionType() == CompletionType.BASIC &&
|
||||
psiElement().withParent(StringLiteralExpression.class).withSuperParent(2, ParameterList.class)
|
||||
.accepts(position, context)) {
|
||||
ParameterListOwner parameterListOwner = PsiTreeUtil.getStubOrPsiParentOfType(position, ParameterListOwner.class);
|
||||
if (parameterListOwner instanceof MethodReference && ((MethodReference)parameterListOwner).isStatic()) {
|
||||
|
||||
Map<String, String> map = getStaticMethodTypesMap(position.getProject()).get(((MethodReference)parameterListOwner).getSignature());
|
||||
for (String s : map.keySet()) {
|
||||
result.addElement(LookupElementBuilder.create(s).appendTailText(map.get(s), true));
|
||||
}
|
||||
}
|
||||
}
|
||||
super.fillCompletionVariants(parameters, result);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
to make completion work registration is required:
|
||||
|
||||
```xml
|
||||
<completion.contributor language="PHP" implementationClass="com.jetbrains.php.lang.psi.resolve.types.PhpStaticFactoryTypeProvider"/>
|
||||
```
|
10
storm/phpstorm.md
Normal file
10
storm/phpstorm.md
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Plugin Development
|
||||
---
|
||||
|
||||
Plugins in PHPStorm developed in Java using IntelliJ IDEA (Community Edition is OK). You will also need a copy of PhpStorm to develop against. The [PsiViewer plugin](https://plugins.jetbrains.com/plugin/?null&pluginId=227) will also be most useful.
|
||||
|
||||
### PhpStorm Specifics
|
||||
* [Setting-up the environment](setting_up_environment.md)
|
||||
* [PHP Open API](php_open_api.md)
|
||||
* [Existing 3rd party plugins](existing_plugins.md)
|
37
storm/setting_up_environment.md
Normal file
37
storm/setting_up_environment.md
Normal file
@ -0,0 +1,37 @@
|
||||
---
|
||||
title: Setting-up environment for PhpStorm plugin development
|
||||
---
|
||||
|
||||
## General information
|
||||
Follow steps that are described at [Getting Started with Plugin Development](http://confluence.jetbrains.com/display/IDEADEV/Getting+Started+with+Plugin+Development).
|
||||
There are two ways to develop plugins for PhpStorm:
|
||||
1. Use Intellij IDEA Ultimate with the PHP plugin installed
|
||||
2. Use PhpStorm as a targeted IDE in a first place.
|
||||
The choice affects how you will configure SDK for the plugin. In the first case you need to specify current installation of Intellij IDEA as SDK and in the second case you need to specify current installation of PhpStorm. This step is described in [Getting Started with Plugin Development](https://confluence.jetbrains.com/display/IDEADEV/Getting+Started+with+Plugin+Development).
|
||||
|
||||
## How to use OpenAPI library
|
||||
|
||||
> OpenAPI is available only for PhpStorm 6 and above.
|
||||
|
||||
This section explains how to configure Intellij IDEA for using PhpStorm OpenAPI.
|
||||
|
||||
### Adding library to a module
|
||||
|
||||
1. Open Project Structure **File \| Project Structure**
|
||||
2. Select **Libraries**
|
||||
3. Press **Add** button
|
||||
4. Find and select `php-openapi.jar` and `php.jar`. They are located in `<your_installation_of_PhpStorm>/plugins/php/lib`.
|
||||

|
||||
5. Agree to add the libraries to your Module
|
||||
6. Open **Modules \| Dependencies** and change **Scope** to **Provided**. This step is necessary because otherwise `ClassCastException` will be thrown because two instances of the library will be loaded via different class loaders
|
||||

|
||||
|
||||
### Adding dependencies to `plugin.xml`
|
||||
|
||||
1. Open `plugin.xml` in the directory `META-INF`
|
||||
2. Add two `<depends>` items to `plugin.xml`:
|
||||
|
||||
```xml
|
||||
<depends>com.jetbrains.php</depends>
|
||||
<depends>com.intellij.modules.platform</depends>
|
||||
```
|
Loading…
x
Reference in New Issue
Block a user