mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
register TreeGenerator and TreeCopyHandler via extension points
This commit is contained in:
@@ -40,7 +40,6 @@ import com.intellij.psi.impl.source.JavaDummyHolderFactory;
|
||||
import com.intellij.psi.impl.source.jsp.jspXml.JspDirective;
|
||||
import com.intellij.psi.impl.source.resolve.FileContextUtil;
|
||||
import com.intellij.psi.impl.source.resolve.PsiResolveHelperImpl;
|
||||
import com.intellij.psi.impl.source.tree.JavaChangeUtilSupport;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
@@ -120,7 +119,6 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable {
|
||||
);
|
||||
|
||||
|
||||
JavaChangeUtilSupport.setup();
|
||||
DummyHolderFactory.setFactory(new JavaDummyHolderFactory());
|
||||
JavaElementType.ANNOTATION.getIndex(); // Initialize stubs.
|
||||
Disposer.register(project, this);
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.impl.source.tree;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.StdLanguages;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl;
|
||||
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
|
||||
import com.intellij.psi.templateLanguages.OuterLanguageElement;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class JavaTreeCopyHandler implements TreeCopyHandler {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.JavaTreeCopyHandler");
|
||||
|
||||
public TreeElement decodeInformation(TreeElement element, final Map<Object, Object> decodingState) {
|
||||
boolean shallDecodeEscapedTexts = shallEncodeEscapedTexts(element, decodingState);
|
||||
if (element instanceof CompositeElement) {
|
||||
if (element.getElementType() == JavaElementType.JAVA_CODE_REFERENCE ||
|
||||
element.getElementType() == JavaElementType.REFERENCE_EXPRESSION) {
|
||||
PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(element);
|
||||
final PsiClass refClass = element.getCopyableUserData(JavaTreeGenerator.REFERENCED_CLASS_KEY);
|
||||
if (refClass != null) {
|
||||
element.putCopyableUserData(JavaTreeGenerator.REFERENCED_CLASS_KEY, null);
|
||||
|
||||
PsiManager manager = refClass.getManager();
|
||||
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(refClass.getProject());
|
||||
PsiElement refElement1 = ref.resolve();
|
||||
try {
|
||||
if (refClass != refElement1 && !manager.areElementsEquivalent(refClass, refElement1)) {
|
||||
if (((CompositeElement)element).findChildByRole(ChildRole.QUALIFIER) == null) {
|
||||
// can restore only if short (otherwise qualifier should be already restored)
|
||||
ref = (PsiJavaCodeReferenceElement)ref.bindToElement(refClass);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// shorten references to the same package and to inner classes that can be accessed by short name
|
||||
ref = (PsiJavaCodeReferenceElement)codeStyleManager.shortenClassReferences(ref, JavaCodeStyleManager.DO_NOT_ADD_IMPORTS);
|
||||
}
|
||||
return (TreeElement)SourceTreeToPsiMap.psiElementToTree(ref);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
((PsiImportHolder) ref.getContainingFile()).importClass(refClass);
|
||||
}
|
||||
}
|
||||
else {
|
||||
final PsiMember refMember = element.getCopyableUserData(JavaTreeGenerator.REFERENCED_MEMBER_KEY);
|
||||
if (refMember != null) {
|
||||
LOG.assertTrue(ref instanceof PsiReferenceExpression);
|
||||
element.putCopyableUserData(JavaTreeGenerator.REFERENCED_MEMBER_KEY, null);
|
||||
PsiElement refElement1 = ref.resolve();
|
||||
if (refMember != refElement1 && !refMember.getManager().areElementsEquivalent(refMember, refElement1)) {
|
||||
try {
|
||||
ref = (PsiJavaCodeReferenceElement) ((PsiReferenceExpression)ref).bindToElementViaStaticImport(refMember.getContainingClass());
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
// TODO[yole] ignore?
|
||||
}
|
||||
return (TreeElement)SourceTreeToPsiMap.psiElementToTree(ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (element.getElementType() == JavaElementType.MODIFIER_LIST) {
|
||||
if (element.getUserData(INTERFACE_MODIFIERS_FLAG_KEY) != null) {
|
||||
element.putUserData(INTERFACE_MODIFIERS_FLAG_KEY, null);
|
||||
try {
|
||||
PsiModifierList modifierList = (PsiModifierList)SourceTreeToPsiMap.treeElementToPsi(element);
|
||||
if (element.getTreeParent().getElementType() == JavaElementType.FIELD) {
|
||||
modifierList.setModifierProperty(PsiModifier.PUBLIC, true);
|
||||
modifierList.setModifierProperty(PsiModifier.STATIC, true);
|
||||
modifierList.setModifierProperty(PsiModifier.FINAL, true);
|
||||
}
|
||||
else if (element.getTreeParent().getElementType() == JavaElementType.METHOD ||
|
||||
element.getTreeParent().getElementType() == JavaElementType.ANNOTATION_METHOD) {
|
||||
modifierList.setModifierProperty(PsiModifier.PUBLIC, true);
|
||||
modifierList.setModifierProperty(PsiModifier.ABSTRACT, true);
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (shallDecodeEscapedTexts && element instanceof LeafElement && !(element instanceof OuterLanguageElement)) {
|
||||
if (!isInCData(element)) {
|
||||
final String original = element.getText();
|
||||
final String escaped = StringUtil.escapeXml(original);
|
||||
if (!Comparing.equal(original, escaped) && element.getCopyableUserData(ALREADY_ESCAPED) == null) {
|
||||
LeafElement copy = ((LeafElement)element).replaceWithText(escaped);
|
||||
copy.putCopyableUserData(ALREADY_ESCAPED, Boolean.TRUE);
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final Key<Boolean> ALREADY_ESCAPED = new Key<Boolean>("ALREADY_ESCAPED");
|
||||
private static final Key<Boolean> ESCAPEMENT_ENGAGED = new Key<Boolean>("ESCAPEMENT_ENGAGED");
|
||||
private static boolean conversionMayApply(ASTNode element) {
|
||||
PsiElement psi = element.getPsi();
|
||||
if (psi == null || !psi.isValid()) return false;
|
||||
|
||||
final PsiFile file = psi.getContainingFile();
|
||||
final Language baseLanguage = file.getViewProvider().getBaseLanguage();
|
||||
return baseLanguage == StdLanguages.JSPX && file.getLanguage() != baseLanguage;
|
||||
}
|
||||
|
||||
|
||||
public void encodeInformation(final TreeElement element, final ASTNode original, final Map<Object, Object> encodingState) {
|
||||
boolean shallEncodeEscapedTexts = shallEncodeEscapedTexts(original, encodingState);
|
||||
|
||||
if (original instanceof CompositeElement) {
|
||||
if (original.getElementType() == JavaElementType.JAVA_CODE_REFERENCE || original.getElementType() == JavaElementType.REFERENCE_EXPRESSION) {
|
||||
encodeInformationInRef(element, original);
|
||||
}
|
||||
else if (original.getElementType() == JavaElementType.MODIFIER_LIST
|
||||
&& (original.getTreeParent().getElementType() == JavaElementType.FIELD || original.getTreeParent().getElementType() == JavaElementType.METHOD || original.getTreeParent().getElementType() == JavaElementType.ANNOTATION_METHOD)
|
||||
&& original.getTreeParent().getTreeParent().getElementType() == JavaElementType.CLASS
|
||||
&& (((PsiClass)SourceTreeToPsiMap.treeElementToPsi(original.getTreeParent().getTreeParent())).isInterface()
|
||||
|| ((PsiClass)SourceTreeToPsiMap.treeElementToPsi(original.getTreeParent().getTreeParent())).isAnnotationType())) {
|
||||
element.putUserData(INTERFACE_MODIFIERS_FLAG_KEY, Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
else if (shallEncodeEscapedTexts && original instanceof LeafElement && !(original instanceof OuterLanguageElement)) {
|
||||
if (!isInCData(original)) {
|
||||
final String originalText = element.getText();
|
||||
final String unescapedText = StringUtil.unescapeXml(originalText);
|
||||
if (!Comparing.equal(originalText, unescapedText)) {
|
||||
LeafElement replaced = ((LeafElement)element).rawReplaceWithText(unescapedText);
|
||||
element.putCopyableUserData(ALREADY_ESCAPED, null);
|
||||
replaced.putCopyableUserData(ALREADY_ESCAPED, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Boolean shallEncodeEscapedTexts(final ASTNode original, final Map<Object, Object> encodingState) {
|
||||
Boolean shallEncodeEscapedTexts = (Boolean)encodingState.get(ESCAPEMENT_ENGAGED);
|
||||
if (shallEncodeEscapedTexts == null) {
|
||||
shallEncodeEscapedTexts = conversionMayApply(original);
|
||||
encodingState.put(ESCAPEMENT_ENGAGED, shallEncodeEscapedTexts);
|
||||
}
|
||||
return shallEncodeEscapedTexts;
|
||||
}
|
||||
|
||||
private static boolean isInCData(ASTNode element) {
|
||||
ASTNode leaf = element;
|
||||
while (leaf != null) {
|
||||
if (leaf instanceof OuterLanguageElement) {
|
||||
return leaf.getText().indexOf("<![CDATA[") >= 0;
|
||||
}
|
||||
|
||||
leaf = TreeUtil.prevLeaf(leaf);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void encodeInformationInRef(TreeElement ref, ASTNode original) {
|
||||
if (original.getElementType() == JavaElementType.REFERENCE_EXPRESSION) {
|
||||
final PsiJavaCodeReferenceElement javaRefElement = (PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(original);
|
||||
assert javaRefElement != null;
|
||||
final JavaResolveResult resolveResult = javaRefElement.advancedResolve(false);
|
||||
final PsiElement target = resolveResult.getElement();
|
||||
if (target instanceof PsiClass &&
|
||||
original.getTreeParent().getElementType() == JavaElementType.REFERENCE_EXPRESSION) {
|
||||
ref.putCopyableUserData(JavaTreeGenerator.REFERENCED_CLASS_KEY, (PsiClass)target);
|
||||
}
|
||||
else if ((target instanceof PsiMethod || target instanceof PsiField) &&
|
||||
((PsiMember) target).hasModifierProperty(PsiModifier.STATIC) &&
|
||||
resolveResult.getCurrentFileResolveScope() instanceof PsiImportStaticStatement) {
|
||||
ref.putCopyableUserData(JavaTreeGenerator.REFERENCED_MEMBER_KEY, (PsiMember) target);
|
||||
}
|
||||
}
|
||||
else if (original.getElementType() == JavaElementType.JAVA_CODE_REFERENCE) {
|
||||
switch (((PsiJavaCodeReferenceElementImpl)original).getKind()) {
|
||||
case PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND:
|
||||
case PsiJavaCodeReferenceElementImpl.CLASS_OR_PACKAGE_NAME_KIND:
|
||||
case PsiJavaCodeReferenceElementImpl.CLASS_IN_QUALIFIED_NEW_KIND:
|
||||
final PsiElement target = SourceTreeToPsiMap.<PsiJavaCodeReferenceElement>treeToPsiNotNull(original).resolve();
|
||||
if (target instanceof PsiClass) {
|
||||
ref.putCopyableUserData(JavaTreeGenerator.REFERENCED_CLASS_KEY, (PsiClass)target);
|
||||
}
|
||||
break;
|
||||
|
||||
case PsiJavaCodeReferenceElementImpl.PACKAGE_NAME_KIND:
|
||||
case PsiJavaCodeReferenceElementImpl.CLASS_FQ_NAME_KIND:
|
||||
case PsiJavaCodeReferenceElementImpl.CLASS_FQ_OR_PACKAGE_NAME_KIND:
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG.assertTrue(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG.error("Wrong element type: " + original.getElementType());
|
||||
}
|
||||
}
|
||||
|
||||
private static final Key<Boolean> INTERFACE_MODIFIERS_FLAG_KEY = Key.create("INTERFACE_MODIFIERS_FLAG_KEY");
|
||||
}
|
||||
+6
-210
@@ -16,39 +16,34 @@
|
||||
|
||||
package com.intellij.psi.impl.source.tree;
|
||||
|
||||
import com.intellij.lang.*;
|
||||
import com.intellij.lang.ASTFactory;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.lang.java.parser.DeclarationParser;
|
||||
import com.intellij.lang.java.parser.JavaParserUtil;
|
||||
import com.intellij.lexer.JavaLexer;
|
||||
import com.intellij.lexer.Lexer;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.impl.GeneratedMarkerVisitor;
|
||||
import com.intellij.psi.impl.light.LightTypeElement;
|
||||
import com.intellij.psi.impl.source.*;
|
||||
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
|
||||
import com.intellij.psi.impl.source.parsing.ParseUtilBase;
|
||||
import com.intellij.psi.templateLanguages.OuterLanguageElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.CharTable;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class JavaChangeUtilSupport implements TreeGenerator, TreeCopyHandler {
|
||||
public class JavaTreeGenerator implements TreeGenerator {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.JavaTreeGenerator");
|
||||
|
||||
private static final JavaParserUtil.ParserWrapper MOD_LIST = new JavaParserUtil.ParserWrapper() {
|
||||
@@ -58,16 +53,6 @@ public class JavaChangeUtilSupport implements TreeGenerator, TreeCopyHandler {
|
||||
}
|
||||
};
|
||||
|
||||
static {
|
||||
final JavaChangeUtilSupport instance = new JavaChangeUtilSupport();
|
||||
ChangeUtil.registerCopyHandler(instance);
|
||||
ChangeUtil.registerTreeGenerator(instance);
|
||||
}
|
||||
|
||||
public static void setup() {
|
||||
// Does nothing, initialization is done in class initializer.
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TreeElement generateTreeFor(PsiElement original, final CharTable table, final PsiManager manager) {
|
||||
if (original instanceof PsiKeyword || original instanceof PsiIdentifier) {
|
||||
@@ -231,194 +216,6 @@ public class JavaChangeUtilSupport implements TreeGenerator, TreeCopyHandler {
|
||||
return element;
|
||||
}
|
||||
|
||||
public TreeElement decodeInformation(TreeElement element, final Map<Object, Object> decodingState) {
|
||||
boolean shallDecodeEscapedTexts = shallEncodeEscapedTexts(element, decodingState);
|
||||
if (element instanceof CompositeElement) {
|
||||
if (element.getElementType() == JavaElementType.JAVA_CODE_REFERENCE ||
|
||||
element.getElementType() == JavaElementType.REFERENCE_EXPRESSION) {
|
||||
PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(element);
|
||||
final PsiClass refClass = element.getCopyableUserData(REFERENCED_CLASS_KEY);
|
||||
if (refClass != null) {
|
||||
element.putCopyableUserData(REFERENCED_CLASS_KEY, null);
|
||||
|
||||
PsiManager manager = refClass.getManager();
|
||||
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(refClass.getProject());
|
||||
PsiElement refElement1 = ref.resolve();
|
||||
try {
|
||||
if (refClass != refElement1 && !manager.areElementsEquivalent(refClass, refElement1)) {
|
||||
if (((CompositeElement)element).findChildByRole(ChildRole.QUALIFIER) == null) {
|
||||
// can restore only if short (otherwise qualifier should be already restored)
|
||||
ref = (PsiJavaCodeReferenceElement)ref.bindToElement(refClass);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// shorten references to the same package and to inner classes that can be accessed by short name
|
||||
ref = (PsiJavaCodeReferenceElement)codeStyleManager.shortenClassReferences(ref, JavaCodeStyleManager.DO_NOT_ADD_IMPORTS);
|
||||
}
|
||||
return (TreeElement)SourceTreeToPsiMap.psiElementToTree(ref);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
((PsiImportHolder) ref.getContainingFile()).importClass(refClass);
|
||||
}
|
||||
}
|
||||
else {
|
||||
final PsiMember refMember = element.getCopyableUserData(REFERENCED_MEMBER_KEY);
|
||||
if (refMember != null) {
|
||||
LOG.assertTrue(ref instanceof PsiReferenceExpression);
|
||||
element.putCopyableUserData(REFERENCED_MEMBER_KEY, null);
|
||||
PsiElement refElement1 = ref.resolve();
|
||||
if (refMember != refElement1 && !refMember.getManager().areElementsEquivalent(refMember, refElement1)) {
|
||||
try {
|
||||
ref = (PsiJavaCodeReferenceElement) ((PsiReferenceExpression)ref).bindToElementViaStaticImport(refMember.getContainingClass());
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
// TODO[yole] ignore?
|
||||
}
|
||||
return (TreeElement)SourceTreeToPsiMap.psiElementToTree(ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (element.getElementType() == JavaElementType.MODIFIER_LIST) {
|
||||
if (element.getUserData(INTERFACE_MODIFIERS_FLAG_KEY) != null) {
|
||||
element.putUserData(INTERFACE_MODIFIERS_FLAG_KEY, null);
|
||||
try {
|
||||
PsiModifierList modifierList = (PsiModifierList)SourceTreeToPsiMap.treeElementToPsi(element);
|
||||
if (element.getTreeParent().getElementType() == JavaElementType.FIELD) {
|
||||
modifierList.setModifierProperty(PsiModifier.PUBLIC, true);
|
||||
modifierList.setModifierProperty(PsiModifier.STATIC, true);
|
||||
modifierList.setModifierProperty(PsiModifier.FINAL, true);
|
||||
}
|
||||
else if (element.getTreeParent().getElementType() == JavaElementType.METHOD ||
|
||||
element.getTreeParent().getElementType() == JavaElementType.ANNOTATION_METHOD) {
|
||||
modifierList.setModifierProperty(PsiModifier.PUBLIC, true);
|
||||
modifierList.setModifierProperty(PsiModifier.ABSTRACT, true);
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (shallDecodeEscapedTexts && element instanceof LeafElement && !(element instanceof OuterLanguageElement)) {
|
||||
if (!isInCData(element)) {
|
||||
final String original = element.getText();
|
||||
final String escaped = StringUtil.escapeXml(original);
|
||||
if (!Comparing.equal(original, escaped) && element.getCopyableUserData(ALREADY_ESCAPED) == null) {
|
||||
LeafElement copy = ((LeafElement)element).replaceWithText(escaped);
|
||||
copy.putCopyableUserData(ALREADY_ESCAPED, Boolean.TRUE);
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final Key<Boolean> ALREADY_ESCAPED = new Key<Boolean>("ALREADY_ESCAPED");
|
||||
private static final Key<Boolean> ESCAPEMENT_ENGAGED = new Key<Boolean>("ESCAPEMENT_ENGAGED");
|
||||
private static boolean conversionMayApply(ASTNode element) {
|
||||
PsiElement psi = element.getPsi();
|
||||
if (psi == null || !psi.isValid()) return false;
|
||||
|
||||
final PsiFile file = psi.getContainingFile();
|
||||
final Language baseLanguage = file.getViewProvider().getBaseLanguage();
|
||||
return baseLanguage == StdLanguages.JSPX && file.getLanguage() != baseLanguage;
|
||||
}
|
||||
|
||||
|
||||
public void encodeInformation(final TreeElement element, final ASTNode original, final Map<Object, Object> encodingState) {
|
||||
boolean shallEncodeEscapedTexts = shallEncodeEscapedTexts(original, encodingState);
|
||||
|
||||
if (original instanceof CompositeElement) {
|
||||
if (original.getElementType() == JavaElementType.JAVA_CODE_REFERENCE || original.getElementType() == JavaElementType.REFERENCE_EXPRESSION) {
|
||||
encodeInformationInRef(element, original);
|
||||
}
|
||||
else if (original.getElementType() == JavaElementType.MODIFIER_LIST
|
||||
&& (original.getTreeParent().getElementType() == JavaElementType.FIELD || original.getTreeParent().getElementType() == JavaElementType.METHOD || original.getTreeParent().getElementType() == JavaElementType.ANNOTATION_METHOD)
|
||||
&& original.getTreeParent().getTreeParent().getElementType() == JavaElementType.CLASS
|
||||
&& (((PsiClass)SourceTreeToPsiMap.treeElementToPsi(original.getTreeParent().getTreeParent())).isInterface()
|
||||
|| ((PsiClass)SourceTreeToPsiMap.treeElementToPsi(original.getTreeParent().getTreeParent())).isAnnotationType())) {
|
||||
element.putUserData(INTERFACE_MODIFIERS_FLAG_KEY, Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
else if (shallEncodeEscapedTexts && original instanceof LeafElement && !(original instanceof OuterLanguageElement)) {
|
||||
if (!isInCData(original)) {
|
||||
final String originalText = element.getText();
|
||||
final String unescapedText = StringUtil.unescapeXml(originalText);
|
||||
if (!Comparing.equal(originalText, unescapedText)) {
|
||||
LeafElement replaced = ((LeafElement)element).rawReplaceWithText(unescapedText);
|
||||
element.putCopyableUserData(ALREADY_ESCAPED, null);
|
||||
replaced.putCopyableUserData(ALREADY_ESCAPED, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Boolean shallEncodeEscapedTexts(final ASTNode original, final Map<Object, Object> encodingState) {
|
||||
Boolean shallEncodeEscapedTexts = (Boolean)encodingState.get(ESCAPEMENT_ENGAGED);
|
||||
if (shallEncodeEscapedTexts == null) {
|
||||
shallEncodeEscapedTexts = conversionMayApply(original);
|
||||
encodingState.put(ESCAPEMENT_ENGAGED, shallEncodeEscapedTexts);
|
||||
}
|
||||
return shallEncodeEscapedTexts;
|
||||
}
|
||||
|
||||
private static boolean isInCData(ASTNode element) {
|
||||
ASTNode leaf = element;
|
||||
while (leaf != null) {
|
||||
if (leaf instanceof OuterLanguageElement) {
|
||||
return leaf.getText().indexOf("<![CDATA[") >= 0;
|
||||
}
|
||||
|
||||
leaf = TreeUtil.prevLeaf(leaf);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void encodeInformationInRef(TreeElement ref, ASTNode original) {
|
||||
if (original.getElementType() == JavaElementType.REFERENCE_EXPRESSION) {
|
||||
final PsiJavaCodeReferenceElement javaRefElement = (PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(original);
|
||||
assert javaRefElement != null;
|
||||
final JavaResolveResult resolveResult = javaRefElement.advancedResolve(false);
|
||||
final PsiElement target = resolveResult.getElement();
|
||||
if (target instanceof PsiClass &&
|
||||
original.getTreeParent().getElementType() == JavaElementType.REFERENCE_EXPRESSION) {
|
||||
ref.putCopyableUserData(REFERENCED_CLASS_KEY, (PsiClass)target);
|
||||
}
|
||||
else if ((target instanceof PsiMethod || target instanceof PsiField) &&
|
||||
((PsiMember) target).hasModifierProperty(PsiModifier.STATIC) &&
|
||||
resolveResult.getCurrentFileResolveScope() instanceof PsiImportStaticStatement) {
|
||||
ref.putCopyableUserData(REFERENCED_MEMBER_KEY, (PsiMember) target);
|
||||
}
|
||||
}
|
||||
else if (original.getElementType() == JavaElementType.JAVA_CODE_REFERENCE) {
|
||||
switch (((PsiJavaCodeReferenceElementImpl)original).getKind()) {
|
||||
case PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND:
|
||||
case PsiJavaCodeReferenceElementImpl.CLASS_OR_PACKAGE_NAME_KIND:
|
||||
case PsiJavaCodeReferenceElementImpl.CLASS_IN_QUALIFIED_NEW_KIND:
|
||||
final PsiElement target = SourceTreeToPsiMap.<PsiJavaCodeReferenceElement>treeToPsiNotNull(original).resolve();
|
||||
if (target instanceof PsiClass) {
|
||||
ref.putCopyableUserData(REFERENCED_CLASS_KEY, (PsiClass)target);
|
||||
}
|
||||
break;
|
||||
|
||||
case PsiJavaCodeReferenceElementImpl.PACKAGE_NAME_KIND:
|
||||
case PsiJavaCodeReferenceElementImpl.CLASS_FQ_NAME_KIND:
|
||||
case PsiJavaCodeReferenceElementImpl.CLASS_FQ_OR_PACKAGE_NAME_KIND:
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG.assertTrue(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG.error("Wrong element type: " + original.getElementType());
|
||||
}
|
||||
}
|
||||
|
||||
private static void encodeInfoInTypeElement(ASTNode typeElement, PsiType type) {
|
||||
if (type instanceof PsiPrimitiveType) return;
|
||||
LOG.assertTrue(typeElement.getElementType() == JavaElementType.TYPE);
|
||||
@@ -491,7 +288,6 @@ public class JavaChangeUtilSupport implements TreeGenerator, TreeCopyHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private static final Key<PsiClass> REFERENCED_CLASS_KEY = Key.create("REFERENCED_CLASS_KEY");
|
||||
private static final Key<PsiMember> REFERENCED_MEMBER_KEY = Key.create("REFERENCED_MEMBER_KEY");
|
||||
private static final Key<Boolean> INTERFACE_MODIFIERS_FLAG_KEY = Key.create("INTERFACE_MODIFIERS_FLAG_KEY");
|
||||
static final Key<PsiClass> REFERENCED_CLASS_KEY = Key.create("REFERENCED_CLASS_KEY");
|
||||
static final Key<PsiMember> REFERENCED_MEMBER_KEY = Key.create("REFERENCED_MEMBER_KEY");
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package com.intellij.psi.impl.source.tree;
|
||||
import com.intellij.lang.ASTFactory;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.pom.PomManager;
|
||||
import com.intellij.pom.PomModel;
|
||||
import com.intellij.pom.event.PomModelEvent;
|
||||
@@ -47,19 +48,9 @@ import java.util.Map;
|
||||
|
||||
public class ChangeUtil {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.ChangeUtil");
|
||||
private static final List<TreeCopyHandler> ourCopyHandlers = ContainerUtil.createEmptyCOWList();
|
||||
private static final List<TreeGenerator> ourTreeGenerators = ContainerUtil.createEmptyCOWList();
|
||||
|
||||
private ChangeUtil() { }
|
||||
|
||||
public static void registerCopyHandler(TreeCopyHandler handler) {
|
||||
ourCopyHandlers.add(handler);
|
||||
}
|
||||
|
||||
public static void registerTreeGenerator(TreeGenerator generator) {
|
||||
ourTreeGenerators.add(generator);
|
||||
}
|
||||
|
||||
public static void changeElementInPlace(final ASTNode element, final ChangeAction action){
|
||||
prepareAndRunChangeAction(new ChangeAction() {
|
||||
public void makeChange(TreeChangeEvent destinationTreeChange) {
|
||||
@@ -68,11 +59,11 @@ public class ChangeUtil {
|
||||
ASTNode node = element;
|
||||
while (node != null) {
|
||||
ASTNode parent = node.getTreeParent();
|
||||
((TreeElement) node).clearCaches();
|
||||
((TreeElement)node).clearCaches();
|
||||
node = parent;
|
||||
}
|
||||
}
|
||||
}, (TreeElement) element);
|
||||
}, (TreeElement)element);
|
||||
}
|
||||
|
||||
public static void encodeInformation(TreeElement element) {
|
||||
@@ -84,7 +75,7 @@ public class ChangeUtil {
|
||||
}
|
||||
|
||||
private static void encodeInformation(TreeElement element, ASTNode original, Map<Object, Object> state) {
|
||||
for (TreeCopyHandler handler : ourCopyHandlers) {
|
||||
for (TreeCopyHandler handler : Extensions.getExtensions(TreeCopyHandler.EP_NAME)) {
|
||||
handler.encodeInformation(element, original, state);
|
||||
}
|
||||
|
||||
@@ -110,7 +101,7 @@ public class ChangeUtil {
|
||||
child = child.getTreeNext();
|
||||
}
|
||||
|
||||
for (TreeCopyHandler handler : ourCopyHandlers) {
|
||||
for (TreeCopyHandler handler : Extensions.getExtensions(TreeCopyHandler.EP_NAME)) {
|
||||
final TreeElement handled = handler.decodeInformation(element, state);
|
||||
if (handled != null) return handled;
|
||||
}
|
||||
@@ -169,7 +160,7 @@ public class ChangeUtil {
|
||||
return copyElement((TreeElement)SourceTreeToPsiMap.psiElementToTree(original), table);
|
||||
}
|
||||
else {
|
||||
for (TreeGenerator generator : ourTreeGenerators) {
|
||||
for (TreeGenerator generator : Extensions.getExtensions(TreeGenerator.EP_NAME)) {
|
||||
final TreeElement element = generator.generateTreeFor(original, table, manager);
|
||||
if (element != null) return element;
|
||||
}
|
||||
|
||||
@@ -20,10 +20,13 @@
|
||||
package com.intellij.psi.impl.source.tree;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface TreeCopyHandler {
|
||||
ExtensionPointName<TreeCopyHandler> EP_NAME = ExtensionPointName.create("com.intellij.treeCopyHandler");
|
||||
|
||||
void encodeInformation(TreeElement element, ASTNode original, Map<Object, Object> encodingState);
|
||||
TreeElement decodeInformation(TreeElement element, Map<Object, Object> decodingState);
|
||||
}
|
||||
@@ -19,12 +19,15 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.source.tree;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.util.CharTable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface TreeGenerator {
|
||||
ExtensionPointName<TreeGenerator> EP_NAME = ExtensionPointName.create("com.intellij.treeGenerator");
|
||||
|
||||
@Nullable
|
||||
TreeElement generateTreeFor(PsiElement original, CharTable table, final PsiManager manager);
|
||||
}
|
||||
@@ -503,4 +503,9 @@
|
||||
|
||||
<extensionPoint name="project.converterProvider"
|
||||
interface="com.intellij.conversion.ConverterProvider"/>
|
||||
|
||||
<extensionPoint name="treeCopyHandler"
|
||||
interface="com.intellij.psi.impl.source.tree.TreeCopyHandler"/>
|
||||
<extensionPoint name="treeGenerator"
|
||||
interface="com.intellij.psi.impl.source.tree.TreeGenerator"/>
|
||||
</extensionPoints>
|
||||
|
||||
@@ -365,6 +365,8 @@
|
||||
|
||||
<postStartupActivity implementation="org.jetbrains.plugins.groovy.mvc.MvcProjectWithoutLibraryNotificator" />
|
||||
|
||||
<treeCopyHandler implementation="org.jetbrains.plugins.groovy.lang.GroovyChangeUtilSupport"/>
|
||||
|
||||
<localInspection language="Groovy" shortName="SecondUnsafeCall" bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
|
||||
key="second.unsafe.call" groupName="Probable bugs" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="org.jetbrains.plugins.groovy.codeInspection.secondUnsafeCall.SecondUnsafeCallInspection"/>
|
||||
@@ -1039,9 +1041,6 @@
|
||||
</actions>
|
||||
|
||||
<application-components>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.plugins.groovy.GroovyLoader</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.plugins.groovy.gant.GantLoader</implementation-class>
|
||||
</component>
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.plugins.groovy;
|
||||
|
||||
import com.intellij.psi.impl.source.tree.ChangeUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.GroovyChangeUtilSupport;
|
||||
|
||||
/**
|
||||
* Main application component, that loads Groovy language support
|
||||
*
|
||||
* @author ilyas
|
||||
*/
|
||||
public class GroovyLoader {
|
||||
|
||||
public GroovyLoader() {
|
||||
ChangeUtil.registerCopyHandler(new GroovyChangeUtilSupport());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1119,6 +1119,9 @@
|
||||
|
||||
<iconLayerProvider implementation="com.intellij.compiler.CompilerIconLayerProvider"/>
|
||||
|
||||
<treeCopyHandler implementation="com.intellij.psi.impl.source.tree.JavaTreeCopyHandler"/>
|
||||
<treeGenerator implementation="com.intellij.psi.impl.source.tree.JavaTreeGenerator"/>
|
||||
|
||||
<projectService serviceImplementation="com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable"/>
|
||||
<projectService serviceInterface="com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemsSettings"
|
||||
serviceImplementation="com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemsSettingsImpl"/>
|
||||
|
||||
Reference in New Issue
Block a user