public String getAttributeValue(String _name, String namespace) { if (namespace == null) { return getAttributeValue(_name); } XmlTagImpl current = this; PsiElement parent = getParent(); while (current != null) { BidirectionalMap<String, String> map = current.initNamespaceMaps(parent); if (map != null) { List<String> keysByValue = map.getKeysByValue(namespace); if (keysByValue != null && !keysByValue.isEmpty()) { for (String prefix : keysByValue) { if (prefix != null && prefix.length() > 0) { final String value = getAttributeValue(prefix + ":" + _name); if (value != null) return value; } } } } current = parent instanceof XmlTag ? (XmlTagImpl) parent : null; parent = parent.getParent(); } if (namespace.length() == 0 || getNamespace().equals(namespace)) { return getAttributeValue(_name); } return null; }
public static PsiElement setName(@NotNull PsiElement element, @NotNull String name) throws IncorrectOperationException { PsiManager manager = element.getManager(); PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); PsiIdentifier newNameIdentifier = factory.createIdentifier(name); return element.replace(newNameIdentifier); }
public PomModelEvent runInner() throws IncorrectOperationException { final ASTNode anchor = expandTag(); if (myChild.getElementType() == XmlElementType.XML_TAG) { // compute where to insert tag according to DTD or XSD final XmlElementDescriptor parentDescriptor = getDescriptor(); final XmlTag[] subTags = getSubTags(); final PsiElement declaration = parentDescriptor != null ? parentDescriptor.getDeclaration() : null; // filtring out generated dtds if (declaration != null && declaration.getContainingFile() != null && declaration.getContainingFile().isPhysical() && subTags.length > 0) { final XmlElementDescriptor[] childElementDescriptors = parentDescriptor.getElementsDescriptors(XmlTagImpl.this); int subTagNum = -1; for (final XmlElementDescriptor childElementDescriptor : childElementDescriptors) { final String childElementName = childElementDescriptor.getName(); while (subTagNum < subTags.length - 1 && subTags[subTagNum + 1].getName().equals(childElementName)) { subTagNum++; } if (childElementName.equals( XmlChildRole.START_TAG_NAME_FINDER.findChild(myChild).getText())) { // insert child just after anchor // insert into the position specified by index if (subTagNum >= 0) { final ASTNode subTag = (ASTNode) subTags[subTagNum]; if (subTag.getTreeParent() != XmlTagImpl.this) { // in entity final XmlEntityRef entityRef = PsiTreeUtil.getParentOfType(subTags[subTagNum], XmlEntityRef.class); throw new IncorrectOperationException( "Can't insert subtag to the entity. Entity reference text: " + (entityRef == null ? "" : entityRef.getText())); } myNewElement = XmlTagImpl.super.addInternal(myChild, myChild, subTag, Boolean.FALSE); } else { final ASTNode child = XmlChildRole.START_TAG_END_FINDER.findChild(XmlTagImpl.this); myNewElement = XmlTagImpl.super.addInternal(myChild, myChild, child, Boolean.FALSE); } return null; } } } else { final ASTNode child = XmlChildRole.CLOSING_TAG_START_FINDER.findChild(XmlTagImpl.this); myNewElement = XmlTagImpl.super.addInternal(myChild, myChild, child, Boolean.TRUE); return null; } } myNewElement = XmlTagImpl.super.addInternal(myChild, myChild, anchor, Boolean.TRUE); return null; }
@Nullable public static PsiModifierList findNeighbourModifierList( @NotNull PsiJavaCodeReferenceElement ref) { PsiElement parent = PsiTreeUtil.skipParentsOfType(ref, PsiJavaCodeReferenceElement.class); if (parent instanceof PsiTypeElement) { PsiElement grandParent = parent.getParent(); if (grandParent instanceof PsiModifierListOwner) { return ((PsiModifierListOwner) grandParent).getModifierList(); } } return null; }
private static boolean isSafeToShortenReference( final String referenceText, final PsiElement psiReference, final PsiClass refClass) { final PsiManager manager = refClass.getManager(); final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject()); final PsiResolveHelper helper = facade.getResolveHelper(); if (manager.areElementsEquivalent( refClass, helper.resolveReferencedClass(referenceText, psiReference))) { PsiElement parent = psiReference.getParent(); if (parent instanceof PsiJavaCodeReferenceElement && parent.getParent() instanceof PsiNewExpression) return true; return helper.resolveReferencedVariable(referenceText, psiReference) == null; } return false; }
@NotNull public String getNamespaceByPrefix(String prefix) { final PsiElement parent = getParent(); LOG.assertTrue(parent.isValid()); BidirectionalMap<String, String> map = initNamespaceMaps(parent); if (map != null) { final String ns = map.get(prefix); if (ns != null) return ns; } if (parent instanceof XmlTag) return ((XmlTag) parent).getNamespaceByPrefix(prefix); // The prefix 'xml' is by definition bound to the namespace name // http://www.w3.org/XML/1998/namespace. It MAY, but need not, be declared if (XML_NS_PREFIX.equals(prefix)) return XmlUtil.XML_NAMESPACE_URI; if (prefix.length() > 0 && !hasNamespaceDeclarations() && getNamespacePrefix().equals(prefix)) { // When there is no namespace declarations then qualified names should be just used in dtds // this implies that we may have "" namespace prefix ! (see last paragraph in Namespaces in // Xml, Section 5) String result = ourGuard.doPreventingRecursion( "getNsByPrefix", true, new Computable<String>() { @Override public String compute() { final String nsFromEmptyPrefix = getNamespaceByPrefix(""); final XmlNSDescriptor nsDescriptor = getNSDescriptor(nsFromEmptyPrefix, false); final XmlElementDescriptor descriptor = nsDescriptor != null ? nsDescriptor.getElementDescriptor(XmlTagImpl.this) : null; final String nameFromRealDescriptor = descriptor != null && descriptor.getDeclaration() != null && descriptor.getDeclaration().isPhysical() ? descriptor.getName() : ""; if (nameFromRealDescriptor.equals(getName())) return nsFromEmptyPrefix; return XmlUtil.EMPTY_URI; } }); if (result != null) { return result; } } return XmlUtil.EMPTY_URI; }
@NotNull public static SearchScope getMemberUseScope(@NotNull PsiMember member) { PsiFile file = member.getContainingFile(); PsiElement topElement = file == null ? member : file; Project project = topElement.getProject(); final GlobalSearchScope maximalUseScope = ResolveScopeManager.getInstance(project).getUseScope(topElement); if (isInServerPage(file)) return maximalUseScope; PsiClass aClass = member.getContainingClass(); if (aClass instanceof PsiAnonymousClass && !(aClass instanceof PsiEnumConstantInitializer && member instanceof PsiMethod && member.hasModifierProperty(PsiModifier.PUBLIC) && ((PsiMethod) member).findSuperMethods().length > 0)) { // member from anonymous class can be called from outside the class PsiElement methodCallExpr = PsiUtil.isLanguageLevel8OrHigher(aClass) ? PsiTreeUtil.getTopmostParentOfType(aClass, PsiStatement.class) : PsiTreeUtil.getParentOfType(aClass, PsiMethodCallExpression.class); return new LocalSearchScope(methodCallExpr != null ? methodCallExpr : aClass); } PsiModifierList modifierList = member.getModifierList(); int accessLevel = modifierList == null ? PsiUtil.ACCESS_LEVEL_PUBLIC : PsiUtil.getAccessLevel(modifierList); if (accessLevel == PsiUtil.ACCESS_LEVEL_PUBLIC || accessLevel == PsiUtil.ACCESS_LEVEL_PROTECTED) { return maximalUseScope; // class use scope doesn't matter, since another very visible class // can inherit from aClass } if (accessLevel == PsiUtil.ACCESS_LEVEL_PRIVATE) { PsiClass topClass = PsiUtil.getTopLevelClass(member); return topClass != null ? new LocalSearchScope(topClass) : file == null ? maximalUseScope : new LocalSearchScope(file); } if (file instanceof PsiJavaFile) { PsiPackage aPackage = JavaPsiFacade.getInstance(project).findPackage(((PsiJavaFile) file).getPackageName()); if (aPackage != null) { SearchScope scope = PackageScope.packageScope(aPackage, false); return scope.intersectWith(maximalUseScope); } } return maximalUseScope; }
public static void sendBeforeChildrenChangeEvent( @NotNull PsiManagerImpl manager, @NotNull PsiElement scope, boolean isGenericChange) { if (!scope.isPhysical()) { manager.beforeChange(false); return; } PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(manager); event.setParent(scope); event.setFile(scope.getContainingFile()); TextRange range = scope.getTextRange(); event.setOffset(range == null ? 0 : range.getStartOffset()); event.setOldLength(scope.getTextLength()); // the "generic" event is being sent on every PSI change. It does not carry any specific info // except the fact that "something has changed" event.setGenericChange(isGenericChange); manager.beforeChildrenChange(event); }
public XmlAttribute setAttribute(String qname, String value) throws IncorrectOperationException { final XmlAttribute attribute = getAttribute(qname); if (attribute != null) { if (value == null) { deleteChildInternal(attribute.getNode()); return null; } attribute.setValue(value); return attribute; } else if (value == null) { return null; } else { PsiElement xmlAttribute = add(XmlElementFactory.getInstance(getProject()).createXmlAttribute(qname, value)); while (!(xmlAttribute instanceof XmlAttribute)) xmlAttribute = xmlAttribute.getNextSibling(); return (XmlAttribute) xmlAttribute; } }
@NotNull public XmlTagValue getValue() { XmlTagValue tagValue = myValue; if (tagValue == null) { final PsiElement[] elements = getElements(); final List<XmlTagChild> bodyElements = new ArrayList<XmlTagChild>(elements.length); boolean insideBody = false; for (final PsiElement element : elements) { final ASTNode treeElement = element.getNode(); if (insideBody) { if (treeElement.getElementType() == XmlTokenType.XML_END_TAG_START) break; if (!(element instanceof XmlTagChild)) continue; bodyElements.add((XmlTagChild) element); } else if (treeElement.getElementType() == XmlTokenType.XML_TAG_END) insideBody = true; } XmlTagChild[] tagChildren = ContainerUtil.toArray(bodyElements, new XmlTagChild[bodyElements.size()]); myValue = tagValue = new XmlTagValueImpl(tagChildren, this); } return tagValue; }
public static PsiType buildTypeFromTypeString( @NotNull final String typeName, @NotNull final PsiElement context, @NotNull final PsiFile psiFile) { PsiType resultType; final PsiManager psiManager = psiFile.getManager(); if (typeName.indexOf('<') != -1 || typeName.indexOf('[') != -1 || typeName.indexOf('.') == -1) { try { return JavaPsiFacade.getInstance(psiManager.getProject()) .getElementFactory() .createTypeFromText(typeName, context); } catch (Exception ignored) { } // invalid syntax will produce unresolved class type } PsiClass aClass = JavaPsiFacade.getInstance(psiManager.getProject()) .findClass(typeName, context.getResolveScope()); if (aClass == null) { final LightClassReference ref = new LightClassReference( psiManager, PsiNameHelper.getShortClassName(typeName), typeName, PsiSubstitutor.EMPTY, psiFile); resultType = new PsiClassReferenceType(ref, null); } else { PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory(); PsiSubstitutor substitutor = factory.createRawSubstitutor(aClass); resultType = factory.createType(aClass, substitutor); } return resultType; }
public TreeElement process(TreeElement element, boolean addImports, boolean uncompleteCode) { IElementType elementType = element.getElementType(); if (elementType == JavaElementType.JAVA_CODE_REFERENCE || elementType == JavaElementType.REFERENCE_EXPRESSION) { final IElementType parentElementType = element.getTreeParent().getElementType(); if (elementType == JavaElementType.JAVA_CODE_REFERENCE || parentElementType == JavaElementType.REFERENCE_EXPRESSION || parentElementType == JavaElementType.METHOD_REF_EXPRESSION || uncompleteCode) { final PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement) SourceTreeToPsiMap.treeElementToPsi(element); final PsiReferenceParameterList parameterList = ref.getParameterList(); if (parameterList != null) { final PsiTypeElement[] typeParameters = parameterList.getTypeParameterElements(); for (PsiTypeElement typeParameter : typeParameters) { process( (TreeElement) SourceTreeToPsiMap.psiElementToTree(typeParameter), addImports, uncompleteCode); } } boolean rightKind = true; if (elementType == JavaElementType.JAVA_CODE_REFERENCE) { int kind = ((PsiJavaCodeReferenceElementImpl) element).getKind(); rightKind = kind == PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND || kind == PsiJavaCodeReferenceElementImpl.CLASS_OR_PACKAGE_NAME_KIND; } if (rightKind) { boolean isInsideDocComment = TreeUtil.findParent(element, JavaDocElementType.DOC_COMMENT) != null; boolean isShort = !((SourceJavaCodeReference) element).isQualified(); if (!makeFQ(isInsideDocComment)) { if (isShort) return element; // short name already, no need to change } PsiElement refElement; if (!uncompleteCode) { refElement = ref.resolve(); } else { PsiResolveHelper helper = JavaPsiFacade.getInstance(element.getManager().getProject()).getResolveHelper(); refElement = helper.resolveReferencedClass( ((SourceJavaCodeReference) element).getClassNameText(), SourceTreeToPsiMap.treeElementToPsi(element)); } if (refElement instanceof PsiClass) { if (makeFQ(isInsideDocComment)) { String qName = ((PsiClass) refElement).getQualifiedName(); if (qName == null) return element; PsiImportHolder file = (PsiImportHolder) SourceTreeToPsiMap.treeElementToPsi(element).getContainingFile(); if (file instanceof PsiJavaFile && ImportHelper.isImplicitlyImported(qName, (PsiJavaFile) file)) { if (isShort) return element; return (TreeElement) makeShortReference( (CompositeElement) element, (PsiClass) refElement, addImports); } if (file instanceof PsiJavaFile) { String thisPackageName = ((PsiJavaFile) file).getPackageName(); if (ImportHelper.hasPackage(qName, thisPackageName)) { if (!isShort) { return (TreeElement) makeShortReference( (CompositeElement) element, (PsiClass) refElement, addImports); } } } return (TreeElement) replaceReferenceWithFQ(element, (PsiClass) refElement); } else { int oldLength = element.getTextLength(); TreeElement treeElement = (TreeElement) makeShortReference( (CompositeElement) element, (PsiClass) refElement, addImports); if (treeElement.getTextLength() == oldLength && ((PsiClass) refElement).getContainingClass() != null) { PsiElement qualifier = ref.getQualifier(); if (qualifier instanceof PsiJavaCodeReferenceElement && ((PsiJavaCodeReferenceElement) qualifier).resolve() instanceof PsiClass) { process((TreeElement) qualifier.getNode(), addImports, uncompleteCode); } } return treeElement; } } } } } for (TreeElement child = element.getFirstChildNode(); child != null; child = child.getTreeNext()) { child = process(child, addImports, uncompleteCode); } return element; }
@Override public ASTNode process( @NotNull ASTNode element, boolean addImports, boolean incompleteCode, boolean useFqInJavadoc, boolean useFqInCode) { IElementType elementType = element.getElementType(); if ((elementType == JavaElementType.JAVA_CODE_REFERENCE || elementType == JavaElementType.REFERENCE_EXPRESSION) && !isAnnotated(element)) { IElementType parentType = element.getTreeParent().getElementType(); if (elementType == JavaElementType.JAVA_CODE_REFERENCE || incompleteCode || parentType == JavaElementType.REFERENCE_EXPRESSION || parentType == JavaElementType.METHOD_REF_EXPRESSION) { PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement) element.getPsi(); PsiReferenceParameterList parameterList = ref.getParameterList(); if (parameterList != null) { PsiTypeElement[] typeParameters = parameterList.getTypeParameterElements(); for (PsiTypeElement typeParameter : typeParameters) { process( typeParameter.getNode(), addImports, incompleteCode, useFqInJavadoc, useFqInCode); } } boolean rightKind = true; if (elementType == JavaElementType.JAVA_CODE_REFERENCE) { PsiJavaCodeReferenceElementImpl impl = (PsiJavaCodeReferenceElementImpl) element; int kind = impl.getKind(impl.getContainingFile()); rightKind = kind == PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND || kind == PsiJavaCodeReferenceElementImpl.CLASS_OR_PACKAGE_NAME_KIND; } if (rightKind) { // annotations may jump out of reference (see PsiJavaCodeReferenceImpl#setAnnotations()) // so they should be processed first List<PsiAnnotation> annotations = PsiTreeUtil.getChildrenOfTypeAsList(ref, PsiAnnotation.class); for (PsiAnnotation annotation : annotations) { process(annotation.getNode(), addImports, incompleteCode, useFqInJavadoc, useFqInCode); } boolean isInsideDocComment = TreeUtil.findParent(element, JavaDocElementType.DOC_COMMENT) != null; boolean isShort = !ref.isQualified(); if (isInsideDocComment ? !useFqInJavadoc : !useFqInCode) { if (isShort) return element; // short name already, no need to change } PsiElement refElement; if (!incompleteCode) { refElement = ref.resolve(); } else { PsiResolveHelper helper = JavaPsiFacade.getInstance(ref.getManager().getProject()).getResolveHelper(); final SourceJavaCodeReference reference = (SourceJavaCodeReference) element; refElement = helper.resolveReferencedClass(reference.getClassNameText(), ref); } if (refElement instanceof PsiClass) { PsiClass psiClass = (PsiClass) refElement; if (isInsideDocComment ? useFqInJavadoc : useFqInCode) { String qName = psiClass.getQualifiedName(); if (qName == null) return element; PsiFile file = ref.getContainingFile(); if (file instanceof PsiJavaFile) { if (ImportHelper.isImplicitlyImported(qName, (PsiJavaFile) file)) { if (isShort) return element; return makeShortReference((CompositeElement) element, psiClass, addImports); } String thisPackageName = ((PsiJavaFile) file).getPackageName(); if (ImportHelper.hasPackage(qName, thisPackageName)) { if (!isShort) { return makeShortReference((CompositeElement) element, psiClass, addImports); } } } return replaceReferenceWithFQ(element, psiClass); } else { int oldLength = element.getTextLength(); ASTNode treeElement = makeShortReference((CompositeElement) element, psiClass, addImports); if (treeElement.getTextLength() == oldLength && psiClass.getContainingClass() != null) { PsiElement qualifier = ref.getQualifier(); if (qualifier instanceof PsiJavaCodeReferenceElement && ((PsiJavaCodeReferenceElement) qualifier).resolve() instanceof PsiClass) { process( qualifier.getNode(), addImports, incompleteCode, useFqInJavadoc, useFqInCode); } } return treeElement; } } } } } for (ASTNode child = element.getFirstChildNode(); child != null; child = child.getTreeNext()) { //noinspection AssignmentToForLoopParameter child = process(child, addImports, incompleteCode, useFqInJavadoc, useFqInCode); } return element; }