mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-80399 @Language in Groovy files
This commit is contained in:
+16
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,7 +23,7 @@ import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.module.ModuleUtil;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogBuilder;
|
||||
@@ -197,21 +197,26 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo
|
||||
else if (parent instanceof PsiVariable) {
|
||||
if (doAddLanguageAnnotation(project, (PsiModifierListOwner)parent, languageId)) return true;
|
||||
}
|
||||
else if (target instanceof PsiVariable) {
|
||||
if (doAddLanguageAnnotation(project, (PsiModifierListOwner)target, languageId)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean doAddLanguageAnnotation(final Project project, final PsiModifierListOwner modifierListOwner,
|
||||
final String languageId) {
|
||||
public static boolean doAddLanguageAnnotation(final Project project, final PsiModifierListOwner modifierListOwner, final String languageId) {
|
||||
if (!Configuration.getProjectInstance(project).getAdvancedConfiguration().isSourceModificationAllowed()) return false;
|
||||
if (modifierListOwner.getModifierList() == null || !PsiUtil.isLanguageLevel5OrHigher(modifierListOwner)) return false;
|
||||
if (!OrderEntryFix.isAnnotationsJarInPath(ModuleUtil.findModuleForPsiElement(modifierListOwner))) {
|
||||
if (!OrderEntryFix.isAnnotationsJarInPath(ModuleUtilCore.findModuleForPsiElement(modifierListOwner))) {
|
||||
// todo add languageId comment
|
||||
return false;
|
||||
}
|
||||
new WriteCommandAction(project, modifierListOwner.getContainingFile()) {
|
||||
protected void run(final Result result) throws Throwable {
|
||||
final PsiAnnotation annotation = JavaPsiFacade.getInstance(project).getElementFactory()
|
||||
.createAnnotationFromText("@" + AnnotationUtil.LANGUAGE + "(\"" + languageId + "\")", modifierListOwner);
|
||||
JVMElementFactory factory = JVMElementFactories.getFactory(modifierListOwner.getLanguage(), modifierListOwner.getProject());
|
||||
if (factory == null) {
|
||||
factory = JavaPsiFacade.getElementFactory(modifierListOwner.getProject());
|
||||
}
|
||||
final PsiAnnotation annotation = factory.createAnnotationFromText("@" + AnnotationUtil.LANGUAGE + "(\"" + languageId + "\")", modifierListOwner);
|
||||
final PsiModifierList list = modifierListOwner.getModifierList();
|
||||
assert list != null;
|
||||
final PsiAnnotation existingAnnotation = list.findAnnotation(AnnotationUtil.LANGUAGE);
|
||||
@@ -227,8 +232,10 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean doInjectInJavaMethod(final Project project, final PsiMethod psiMethod, final int parameterIndex,
|
||||
final String languageId) {
|
||||
public static boolean doInjectInJavaMethod(@NotNull final Project project,
|
||||
@Nullable final PsiMethod psiMethod,
|
||||
final int parameterIndex,
|
||||
@NotNull final String languageId) {
|
||||
if (psiMethod == null) return false;
|
||||
if (parameterIndex < -1) return false;
|
||||
if (parameterIndex >= psiMethod.getParameterList().getParametersCount()) return false;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<orderEntry type="module" module-name="ant" />
|
||||
<orderEntry type="library" name="Guava" level="project" />
|
||||
<orderEntry type="module" module-name="testFramework-java" scope="TEST" />
|
||||
<orderEntry type="module" module-name="IntelliLang-java" scope="TEST" />
|
||||
<orderEntry type="module" module-name="IntelliLang-java" />
|
||||
<orderEntry type="module" module-name="IntelliLang-xml" scope="TEST" />
|
||||
<orderEntry type="module" module-name="jps-builders" />
|
||||
<orderEntry type="module" module-name="spellchecker" />
|
||||
|
||||
+125
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,13 +16,36 @@
|
||||
|
||||
package org.intellij.plugins.intelliLang.inject.groovy;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.light.LightElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.intellij.plugins.intelliLang.inject.AbstractLanguageInjectionSupport;
|
||||
import org.intellij.plugins.intelliLang.inject.java.JavaLanguageInjectionSupport;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationArrayInitializer;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationNameValuePair;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.literals.GrLiteralImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.patterns.GroovyPatterns;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Gregory.Shrago
|
||||
*/
|
||||
@@ -47,4 +70,104 @@ public class GroovyLanguageInjectionSupport extends AbstractLanguageInjectionSup
|
||||
public String getHelpId() {
|
||||
return "reference.settings.language.injection.groovy";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addInjectionInPlace(Language language, PsiLanguageInjectionHost psiElement) {
|
||||
if (!isStringLiteral(psiElement)) return false;
|
||||
|
||||
|
||||
return doInject(language.getID(), psiElement);
|
||||
}
|
||||
|
||||
private static boolean doInject(String languageId, PsiElement host) {
|
||||
final PsiElement target = getTopLevelInjectionTarget(host);
|
||||
final PsiElement parent = target.getParent();
|
||||
final Project project = host.getProject();
|
||||
|
||||
if (parent instanceof GrReturnStatement) {
|
||||
final GrControlFlowOwner owner = ControlFlowUtils.findControlFlowOwner(parent);
|
||||
if (owner instanceof GrOpenBlock && owner.getParent() instanceof GrMethod) {
|
||||
return JavaLanguageInjectionSupport.doInjectInJavaMethod(project, (PsiMethod)owner.getParent(), -1, languageId);
|
||||
}
|
||||
}
|
||||
else if (parent instanceof GrMethod) {
|
||||
return JavaLanguageInjectionSupport.doInjectInJavaMethod(project, (GrMethod)parent, -1, languageId);
|
||||
}
|
||||
else if (parent instanceof GrAnnotationNameValuePair) {
|
||||
final PsiReference ref = parent.getReference();
|
||||
if (ref != null) {
|
||||
final PsiElement resolved = ref.resolve();
|
||||
if (resolved instanceof PsiMethod) {
|
||||
return JavaLanguageInjectionSupport.doInjectInJavaMethod(project, (PsiMethod)resolved, -1, languageId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (parent instanceof GrArgumentList && parent.getParent() instanceof GrMethodCall) {
|
||||
final PsiMethod method = ((GrMethodCall)parent.getParent()).resolveMethod();
|
||||
if (method != null) {
|
||||
final int index = findParameterIndex(target, ((GrMethodCall)parent.getParent()));
|
||||
if (index >= 0) {
|
||||
return JavaLanguageInjectionSupport.doInjectInJavaMethod(project, method, index, languageId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (parent instanceof GrAssignmentExpression) {
|
||||
final GrExpression expr = ((GrAssignmentExpression)parent).getLValue();
|
||||
if (expr instanceof GrReferenceExpression) {
|
||||
final PsiElement element = ((GrReferenceExpression)expr).resolve();
|
||||
if (element != null) {
|
||||
return doInject(languageId, element);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (parent instanceof PsiVariable) {
|
||||
if (JavaLanguageInjectionSupport.doAddLanguageAnnotation(project, (PsiModifierListOwner)parent, languageId)) return true;
|
||||
}
|
||||
else if (target instanceof PsiVariable && !(target instanceof LightElement)) {
|
||||
if (JavaLanguageInjectionSupport.doAddLanguageAnnotation(project, (PsiModifierListOwner)target, languageId)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int findParameterIndex(PsiElement arg, GrMethodCall call) {
|
||||
final GroovyResolveResult result = call.advancedResolve();
|
||||
assert result.getElement() instanceof PsiMethod;
|
||||
final Map<GrExpression, Pair<PsiParameter, PsiType>> map = GrClosureSignatureUtil
|
||||
.mapArgumentsToParameters(result, call, false, false, call.getNamedArguments(), call.getExpressionArguments(),
|
||||
call.getClosureArguments());
|
||||
if (map == null) return -1;
|
||||
|
||||
final PsiMethod method = (PsiMethod)result.getElement();
|
||||
final PsiParameter parameter = map.get(arg).first;
|
||||
if (parameter == null) return -1;
|
||||
|
||||
return method.getParameterList().getParameterIndex(parameter);
|
||||
}
|
||||
|
||||
private static boolean isStringLiteral(PsiLanguageInjectionHost element) {
|
||||
if (element instanceof GrLiteral) {
|
||||
final IElementType type = GrLiteralImpl.getLiteralType((GrLiteral)element);
|
||||
return TokenSets.STRING_LITERALS.contains(type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PsiElement getTopLevelInjectionTarget(@NotNull final PsiElement host) {
|
||||
PsiElement target = host;
|
||||
PsiElement parent = target.getParent();
|
||||
for (; parent != null; target = parent, parent = target.getParent()) {
|
||||
if (parent instanceof GrBinaryExpression) continue;
|
||||
if (parent instanceof GrParenthesizedExpression) continue;
|
||||
if (parent instanceof GrConditionalExpression && ((GrConditionalExpression)parent).getCondition() != target) continue;
|
||||
if (parent instanceof GrAnnotationArrayInitializer) continue;
|
||||
if (parent instanceof GrListOrMap) {
|
||||
parent = parent.getParent(); continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,14 +125,18 @@ public abstract class TokenSets {
|
||||
|
||||
public static final TokenSet STRING_LITERALS = TokenSet.create(
|
||||
mSTRING_LITERAL,
|
||||
mREGEX_CONTENT,
|
||||
mDOLLAR_SLASH_REGEX_CONTENT,
|
||||
mGSTRING_LITERAL,
|
||||
mGSTRING_CONTENT,
|
||||
mGSTRING_BEGIN,
|
||||
mGSTRING_CONTENT,
|
||||
mGSTRING_END,
|
||||
mREGEX_LITERAL,
|
||||
mDOLLAR_SLASH_REGEX_LITERAL
|
||||
mREGEX_BEGIN,
|
||||
mREGEX_CONTENT,
|
||||
mREGEX_END,
|
||||
mDOLLAR_SLASH_REGEX_LITERAL,
|
||||
mDOLLAR_SLASH_REGEX_BEGIN,
|
||||
mDOLLAR_SLASH_REGEX_CONTENT,
|
||||
mDOLLAR_SLASH_REGEX_END
|
||||
);
|
||||
|
||||
public static final TokenSet FOR_IN_DELIMITERS = TokenSet.create(kIN, mCOLON);
|
||||
|
||||
Reference in New Issue
Block a user