IDEA-135780 Language Injection via comment: does not work for concatenated strings in annotations

This commit is contained in:
Gregory.Shrago
2015-01-29 21:48:21 +03:00
parent 0f90f3a7ce
commit 657d92ba50
3 changed files with 41 additions and 29 deletions
@@ -73,12 +73,12 @@ public class ConcatenationInjector implements ConcatenationAwareInjector {
PsiFile containingFile = null;
for (PsiElement operand : operands) {
if (PsiUtilEx.isStringOrCharacterLiteral(operand)) {
hasLiteral = true;
if (containingFile == null) {
containingFile = operands[0].getContainingFile();
}
tempInjectedLanguage = myTemporaryPlacesRegistry.getLanguageFor((PsiLanguageInjectionHost)operand, containingFile);
hasLiteral = true;
if (tempInjectedLanguage != null) break;
}
}
@@ -134,6 +134,13 @@ public class ConcatenationInjector implements ConcatenationAwareInjector {
public void processInjections() {
final PsiElement firstOperand = myOperands[0];
Ref<PsiElement> causeRef = Ref.create();
BaseInjection commentInjection = mySupport.findCommentInjection(firstOperand, causeRef);
if (commentInjection != null) {
processCommentInjectionInner(causeRef.get(), commentInjection);
return;
}
final PsiElement topBlock = PsiUtil.getTopLevelEnclosingCodeBlock(firstOperand, null);
final LocalSearchScope searchScope = new LocalSearchScope(new PsiElement[]{topBlock instanceof PsiCodeBlock
? topBlock : firstOperand.getContainingFile()}, "", true);
@@ -258,10 +265,10 @@ public class ConcatenationInjector implements ConcatenationAwareInjector {
Ref<PsiElement> causeRef = Ref.create();
BaseInjection injection = mySupport.findCommentInjection(anchor, causeRef);
return injection == null || processCommentInjectionInner(owner, causeRef.get(), injection);
return injection == null || processCommentInjectionInner(causeRef.get(), injection);
}
protected boolean processCommentInjectionInner(PsiVariable owner, PsiElement comment, BaseInjection injection) {
protected boolean processCommentInjectionInner(PsiElement comment, BaseInjection injection) {
processInjectionWithContext(injection, false);
return false;
}
@@ -213,7 +213,6 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo
final PsiModifierListOwner modifierListOwner,
@NotNull PsiLanguageInjectionHost host,
final String languageId) {
// todo add languageId comment
return doAddLanguageAnnotation(project, modifierListOwner, host, languageId, new Processor<PsiLanguageInjectionHost>() {
@Override
public boolean process(PsiLanguageInjectionHost host) {
@@ -230,37 +229,42 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo
});
}
public static boolean doAddLanguageAnnotation(final Project project,
final PsiModifierListOwner modifierListOwner,
@NotNull PsiLanguageInjectionHost host,
public static boolean doAddLanguageAnnotation(Project project,
@Nullable final PsiModifierListOwner modifierListOwner,
@NotNull final PsiLanguageInjectionHost host,
final String languageId,
Processor<PsiLanguageInjectionHost> annotationFixer) {
if (modifierListOwner.getModifierList() == null || !PsiUtil.isLanguageLevel5OrHigher(modifierListOwner)) return false;
final Configuration.AdvancedConfiguration configuration = Configuration.getProjectInstance(project).getAdvancedConfiguration();
final boolean addAnnotation = OrderEntryFix.isAnnotationsJarInPath(ModuleUtilCore.findModuleForPsiElement(modifierListOwner))
&& PsiUtil.isLanguageLevel5OrHigher(modifierListOwner)
&& modifierListOwner.getModifierList() != null;
final PsiStatement statement = PsiTreeUtil.getParentOfType(host, PsiStatement.class);
if (!addAnnotation && statement == null) return false;
Configuration.AdvancedConfiguration configuration = Configuration.getProjectInstance(project).getAdvancedConfiguration();
if (!configuration.isSourceModificationAllowed()) {
host.putUserData(InjectLanguageAction.FIX_KEY, annotationFixer);
return false;
}
if (!OrderEntryFix.ensureAnnotationsJarInPath(ModuleUtilCore.findModuleForPsiElement(modifierListOwner))) {
return false;
}
new WriteCommandAction(modifierListOwner.getProject(), modifierListOwner.getContainingFile()) {
protected void run(@NotNull final Result result) throws Throwable {
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);
if (existingAnnotation != null) {
existingAnnotation.replace(annotation);
protected void run(@NotNull Result result) throws Throwable {
PsiElementFactory javaFacade = JavaPsiFacade.getElementFactory(getProject());
if (addAnnotation) {
JVMElementFactory factory = ObjectUtils.chooseNotNull(JVMElementFactories.getFactory(modifierListOwner.getLanguage(), getProject()), javaFacade);
PsiAnnotation annotation = factory.createAnnotationFromText("@" + AnnotationUtil.LANGUAGE + "(\"" + languageId + "\")", modifierListOwner);
PsiModifierList list = ObjectUtils.assertNotNull(modifierListOwner.getModifierList());
final PsiAnnotation existingAnnotation = list.findAnnotation(AnnotationUtil.LANGUAGE);
if (existingAnnotation != null) {
existingAnnotation.replace(annotation);
}
else {
list.addAfter(annotation, null);
}
JavaCodeStyleManager.getInstance(getProject()).shortenClassReferences(list);
}
else {
list.addAfter(annotation, null);
statement.getParent().addBefore(javaFacade.createCommentFromText("//language=" + languageId, host), statement);
}
JavaCodeStyleManager.getInstance(getProject()).shortenClassReferences(list);
}
}.execute();
return true;
@@ -392,7 +396,7 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo
new ConcatenationInjector.InjectionProcessor(configuration, support, host) {
@Override
protected boolean processCommentInjectionInner(PsiVariable owner, PsiElement comment, BaseInjection injection) {
protected boolean processCommentInjectionInner(PsiElement comment, BaseInjection injection) {
ContainerUtil.addAll(annotations, comment);
return true;
}
@@ -19,6 +19,8 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
@@ -45,9 +47,8 @@ public class ContextComputationProcessor {
final ArrayList<Object> result = new ArrayList<Object>();
final ContextComputationProcessor processor = new ContextComputationProcessor(operands[0].getProject());
addStringFragment(prefix, result);
for (PsiElement operand : operands) {
processor.collectOperands(operand, result, unparsable);
}
PsiElement topParent = ObjectUtils.assertNotNull(PsiTreeUtil.findCommonParent(operands));
processor.collectOperands(getTopLevelInjectionTarget(topParent), result, unparsable);
addStringFragment(suffix, result);
return result;
}