public static void cacheParticularEntity(PsiFile file, XmlEntityDecl decl) { synchronized(PsiLock.LOCK) { final Map<String, CachedValue<XmlEntityDecl>> cachingMap = getCachingMap(file); final String name = decl.getName(); if (cachingMap.containsKey(name)) return; final SmartPsiElementPointer declPointer = SmartPointerManager.getInstance(file.getProject()).createSmartPsiElementPointer(decl); cachingMap.put( name, CachedValuesManager.getManager(file.getProject()).createCachedValue(new CachedValueProvider<XmlEntityDecl>() { @Override public Result<XmlEntityDecl> compute() { PsiElement declElement = declPointer.getElement(); if (declElement instanceof XmlEntityDecl && declElement.isValid() && name.equals(((XmlEntityDecl)declElement).getName())) return new Result<XmlEntityDecl>((XmlEntityDecl)declElement, declElement); cachingMap.put(name,null); return new Result<XmlEntityDecl>(null, ModificationTracker.NEVER_CHANGED); } }, false )); } }
public DtdParsing(CharSequence chars, final IElementType type, final XmlEntityDecl.EntityContextType contextType, PsiFile contextFile ) { this( type, contextType, PsiBuilderFactory.getInstance().createBuilder( LanguageParserDefinitions.INSTANCE.forLanguage(DTDLanguage.INSTANCE), new DtdLexer(false) { final int myInitialState = getLexerInitialState(type, contextType); @Override public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) { super.start(buffer, startOffset, endOffset, myInitialState); } }, chars ) ); if (contextFile != null) myBuilder.putUserDataUnprotected(FileContextUtil.CONTAINING_FILE_KEY, contextFile); }
@Override public Object[] get(final PsiElement context, CompletionContext completionContext) { final List<String> results = new LinkedList<String>(); final PsiElementProcessor processor = new PsiElementProcessor() { @Override public boolean execute(@NotNull final PsiElement element) { if (element instanceof XmlEntityDecl) { final XmlEntityDecl xmlEntityDecl = (XmlEntityDecl)element; if (xmlEntityDecl.isInternalReference()) { results.add(xmlEntityDecl.getName()); } } return true; } }; XmlUtil.processXmlElements((XmlFile)context.getContainingFile().getOriginalFile(), processor, true); return ArrayUtil.toObjectArray(results); }
public static void cacheParticularEntity(PsiFile file, XmlEntityDecl decl) { synchronized(PsiLock.LOCK) { final Map<String, CachedValue<XmlEntityDecl>> cachingMap = getCachingMap(file); final String name = decl.getName(); if (cachingMap.containsKey(name)) return; final SmartPsiElementPointer declPointer = SmartPointerManager.getInstance(file.getProject()).createSmartPsiElementPointer(decl); cachingMap.put( name, CachedValuesManager.getManager(file.getProject()).createCachedValue(new CachedValueProvider<XmlEntityDecl>() { public Result<XmlEntityDecl> compute() { PsiElement declElement = declPointer.getElement(); if (declElement instanceof XmlEntityDecl && declElement.isValid() && name.equals(((XmlEntityDecl)declElement).getName())) return new Result<XmlEntityDecl>((XmlEntityDecl)declElement, declElement); cachingMap.put(name,null); return new Result<XmlEntityDecl>(null,null); } }, false )); } }
public DtdParsing(CharSequence chars, final IElementType type, final XmlEntityDecl.EntityContextType contextType, PsiFile contextFile ) { this( type, contextType, PsiBuilderFactory.getInstance().createBuilder( LanguageParserDefinitions.INSTANCE.forLanguage(DTDLanguage.INSTANCE), new DtdLexer(false) { final int myInitialState = getLexerInitialState(type, contextType); @Override public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) { super.start(buffer, startOffset, endOffset, myInitialState); } }, chars ) ); if (contextFile != null) myBuilder.putUserDataUnprotected(FileContextUtil.CONTAINING_FILE_KEY, contextFile); }
public Object[] get(final PsiElement context, CompletionContext completionContext) { final List<String> results = new LinkedList<String>(); final PsiElementProcessor processor = new PsiElementProcessor() { public boolean execute(@NotNull final PsiElement element) { if (element instanceof XmlEntityDecl) { final XmlEntityDecl xmlEntityDecl = (XmlEntityDecl)element; if (xmlEntityDecl.isInternalReference()) { results.add(xmlEntityDecl.getName()); } } return true; } }; XmlUtil.processXmlElements((XmlFile)context.getContainingFile().getOriginalFile(), processor, true); return ArrayUtil.toObjectArray(results); }
public static void cacheParticularEntity(PsiFile file, XmlEntityDecl decl) { synchronized(LOCK) { final Map<String, CachedValue<XmlEntityDecl>> cachingMap = getCachingMap(file); final String name = decl.getName(); if(cachingMap.containsKey(name)) { return; } final SmartPsiElementPointer declPointer = SmartPointerManager.getInstance(file.getProject()).createSmartPsiElementPointer(decl); cachingMap.put(name, CachedValuesManager.getManager(file.getProject()).createCachedValue(() -> { PsiElement declElement = declPointer.getElement(); if(declElement instanceof XmlEntityDecl && declElement.isValid() && name.equals(((XmlEntityDecl) declElement).getName())) { return new CachedValueProvider.Result<>((XmlEntityDecl) declElement, declElement); } cachingMap.put(name, null); return new CachedValueProvider.Result<>(null, ModificationTracker.NEVER_CHANGED); }, false)); } }
public DtdParsing(CharSequence chars, final IElementType type, final XmlEntityDecl.EntityContextType contextType, PsiFile contextFile ) { this( type, contextType, PsiBuilderFactory.getInstance().createBuilder( LanguageParserDefinitions.INSTANCE.forLanguage(DTDLanguage.INSTANCE), new DtdLexer(false) { final int myInitialState = getLexerInitialState(type, contextType); @Override public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) { super.start(buffer, startOffset, endOffset, myInitialState); } }, LanguageVersionUtil.findDefaultVersion(DTDLanguage.INSTANCE), chars ) ); if (contextFile != null) myBuilder.putUserDataUnprotected(FileContextUtil.CONTAINING_FILE_KEY, contextFile); }
private static void addEntityCompletions(@NotNull final CompletionResultSet result, PsiElement position) { final PsiElementProcessor processor = new PsiElementProcessor() { @Override public boolean execute(@NotNull final PsiElement element) { if(element instanceof XmlEntityDecl) { final XmlEntityDecl xmlEntityDecl = (XmlEntityDecl) element; String name = xmlEntityDecl.getName(); if(name != null && xmlEntityDecl.isInternalReference()) { result.addElement(LookupElementBuilder.create(name).withInsertHandler(XmlCompletionContributor.ENTITY_INSERT_HANDLER)); } } return true; } }; XmlUtil.processXmlElements((XmlFile) position.getContainingFile().getOriginalFile(), processor, true); }
@NotNull @Override public PsiParser createParser(Project project) { return new PsiParser() { @NotNull @Override public ASTNode parse(IElementType root, PsiBuilder builder) { return new DtdParsing(root, XmlEntityDecl.EntityContextType.GENERIC_XML, builder).parse(); } }; }
static Map<String, CachedValue<XmlEntityDecl>> getCachingMap(final PsiElement targetElement) { Map<String, CachedValue<XmlEntityDecl>> map = targetElement.getUserData(XML_ENTITY_DECL_MAP); if (map == null){ map = new HashMap<String,CachedValue<XmlEntityDecl>>(); targetElement.putUserData(XML_ENTITY_DECL_MAP, map); } return map; }
public static void copyEntityCaches(final PsiFile file, final PsiFile context) { synchronized (PsiLock.LOCK) { final Map<String, CachedValue<XmlEntityDecl>> cachingMap = getCachingMap(file); for(Map.Entry<String,CachedValue<XmlEntityDecl>> entry:getCachingMap(context).entrySet()) { cachingMap.put(entry.getKey(), entry.getValue()); } } }
public static XmlEntityDecl getCachedEntity(PsiFile file, String name) { CachedValue<XmlEntityDecl> cachedValue; synchronized(PsiLock.LOCK) { final Map<String, CachedValue<XmlEntityDecl>> cachingMap = getCachingMap(file); cachedValue = cachingMap.get(name); } return cachedValue != null ? cachedValue.getValue():null; }
private static int getLexerInitialState(IElementType rootNodeType, XmlEntityDecl.EntityContextType context) { short state = 0; switch (context) { case ELEMENT_CONTENT_SPEC: case ATTRIBUTE_SPEC: case ATTLIST_SPEC: case ENUMERATED_TYPE: case ENTITY_DECL_CONTENT: { state = _DtdLexer.DOCTYPE_MARKUP; break; } case ATTR_VALUE: case GENERIC_XML: { break; } default: LOG.error("context: " + context); } if (rootNodeType == XML_MARKUP_DECL && context == TYPE_FOR_MARKUP_DECL) { state = _DtdLexer.DOCTYPE; } return state; }
private static void loadEntities(final Project project) { if (ourEntities != null) return; final XmlFile file; try { final String url = ExternalResourceManager.getInstance().getResourceLocation(XmlUtil.HTML4_LOOSE_URI, project); if (url == null) { LOG.error("Namespace not found: " + XmlUtil.HTML4_LOOSE_URI); return; } final VirtualFile vFile = VfsUtil.findFileByURL(new URL(url)); if (vFile == null) { LOG.error("Resource not found: " + url); return; } final PsiFile psiFile = PsiManager.getInstance(project).findFile(vFile); if (!(psiFile instanceof XmlFile)) { LOG.error("Unexpected resource: " + psiFile); return; } file = (XmlFile)psiFile; } catch (MalformedURLException e) { LOG.error(e); return; } ourEntities = new HashMap<Character, String>(); final Pattern pattern = Pattern.compile("&#(\\d+);"); XmlUtil.processXmlElements(file, new PsiElementProcessor() { @Override public boolean execute(@NotNull PsiElement element) { if (element instanceof XmlEntityDecl) { final XmlEntityDecl entity = (XmlEntityDecl)element; final Matcher m = pattern.matcher(entity.getValueElement().getValue()); if (m.matches()) { final char i = (char)Integer.parseInt(m.group(1)); if (shouldConvert(i)) { ourEntities.put(i, entity.getName()); } } } return true; } }, true); }
static Map<String, CachedValue<XmlEntityDecl>> getCachingMap(final PsiElement targetElement) { Map<String, CachedValue<XmlEntityDecl>> map = targetElement.getUserData(XML_ENTITY_DECL_MAP); if(map == null) { map = new HashMap<>(); targetElement.putUserData(XML_ENTITY_DECL_MAP, map); } return map; }
public static void copyEntityCaches(final PsiFile file, final PsiFile context) { synchronized(LOCK) { final Map<String, CachedValue<XmlEntityDecl>> cachingMap = getCachingMap(file); for(Map.Entry<String, CachedValue<XmlEntityDecl>> entry : getCachingMap(context).entrySet()) { cachingMap.put(entry.getKey(), entry.getValue()); } } }
public static XmlEntityDecl getCachedEntity(PsiFile file, String name) { CachedValue<XmlEntityDecl> cachedValue; synchronized(LOCK) { final Map<String, CachedValue<XmlEntityDecl>> cachingMap = getCachingMap(file); cachedValue = cachingMap.get(name); } return cachedValue != null ? cachedValue.getValue() : null; }
@Nullable private static LookupElementBuilder buildEntityLookupItem(@NotNull final XmlEntityDecl decl) { final String name = decl.getName(); if(name == null) { return null; } final LookupElementBuilder result = LookupElementBuilder.create(name).withInsertHandler(ENTITY_INSERT_HANDLER); final XmlAttributeValue value = decl.getValueElement(); final ASTNode node = value.getNode(); if(node != null) { final ASTNode[] nodes = node.getChildren(TokenSet.create(XmlTokenType.XML_CHAR_ENTITY_REF)); if(nodes.length == 1) { final String valueText = nodes[0].getText(); final int i = valueText.indexOf('#'); if(i > 0) { String s = valueText.substring(i + 1); s = StringUtil.trimEnd(s, ";"); try { final int unicodeChar = Integer.valueOf(s).intValue(); return result.withTypeText(String.valueOf((char) unicodeChar)); } catch(NumberFormatException e) { return result; } } } } return result; }
@Override public void contributeMetaData(final MetaDataRegistrar registrar) { { registrar.registerMetaData(new AndFilter(new NamespaceFilter(XmlUtil.SCHEMA_URIS), new ClassFilter(XmlDocument.class)), SchemaNSDescriptor.class); registrar.registerMetaData(new AndFilter(XmlTagFilter.INSTANCE, new NamespaceFilter(XmlUtil.SCHEMA_URIS), new XmlTextFilter("schema")), SchemaNSDescriptor.class); } { registrar.registerMetaData(new OrFilter(new AndFilter(new ContentFilter(new OrFilter(new ClassFilter(XmlElementDecl.class), new ClassFilter(XmlEntityDecl.class), new ClassFilter (XmlConditionalSection.class), new ClassFilter(XmlEntityRef.class))), new ClassFilter(XmlDocument.class)), new ClassFilter(XmlMarkupDecl.class)), XmlNSDescriptorImpl.class); } { registrar.registerMetaData(new AndFilter(XmlTagFilter.INSTANCE, new NamespaceFilter(XmlUtil.SCHEMA_URIS), new XmlTextFilter("element")), XmlElementDescriptorImpl.class); } { registrar.registerMetaData(new AndFilter(XmlTagFilter.INSTANCE, new NamespaceFilter(XmlUtil.SCHEMA_URIS), new XmlTextFilter("attribute")), XmlAttributeDescriptorImpl.class); } { registrar.registerMetaData(new ClassFilter(XmlElementDecl.class), com.intellij.xml.impl.dtd.XmlElementDescriptorImpl.class); } { registrar.registerMetaData(new ClassFilter(XmlAttributeDecl.class), com.intellij.xml.impl.dtd.XmlAttributeDescriptorImpl.class); } { registrar.registerMetaData(new AndFilter(new ClassFilter(XmlDocument.class), new TargetNamespaceFilter(XmlUtil.XHTML_URI), new NamespaceFilter(XmlUtil.SCHEMA_URIS)), RelaxedHtmlFromSchemaNSDescriptor.class); } { registrar.registerMetaData(new AndFilter(XmlTagFilter.INSTANCE, new NamespaceFilter(XmlUtil.SCHEMA_URIS), new XmlTextFilter("complexType", "simpleType", "group", "attributeGroup")), NamedObjectDescriptor.class); } }
@Override @NotNull public String getType(@NotNull PsiElement element) { if(element instanceof XmlTag) { final PsiMetaData metaData = ((XmlTag) element).getMetaData(); if(metaData != null && metaData.getDeclaration() instanceof XmlTag) { return ((XmlTag) metaData.getDeclaration()).getName(); } return LangBundle.message("xml.terms.xml.tag"); } if(element instanceof XmlElementDecl) { return LangBundle.message("xml.terms.tag"); } else if(element instanceof XmlAttributeDecl) { return LangBundle.message("xml.terms.attribute"); } else if(element instanceof XmlAttributeValue) { return LangBundle.message("xml.terms.attribute.value"); } else if(element instanceof XmlEntityDecl) { return LangBundle.message("xml.terms.entity"); } else if(element instanceof XmlAttribute) { return LangBundle.message("xml.terms.attribute"); } else if(element instanceof XmlComment) { return LangBundle.message("xml.terms.variable"); } throw new IllegalArgumentException("Cannot get type for " + element); }
public DtdParsing(IElementType root, XmlEntityDecl.EntityContextType contextType, PsiBuilder builder) { super(builder); myRootType = root; myContextType = contextType; myBuilder.enforceCommentTokens(TokenSet.EMPTY); }
@Override public boolean isIncluded(PsiFile targetFile) { ASTNode child = findChildByType(XmlTokenType.XML_CONDITIONAL_SECTION_START); if(child != null) { child = child.getTreeNext(); if(child != null && child.getElementType() == TokenType.WHITE_SPACE) { child = child.getTreeNext(); } if(child != null) { IElementType elementType = child.getElementType(); if(elementType == XmlTokenType.XML_CONDITIONAL_INCLUDE) { return true; } if(elementType == XmlTokenType.XML_CONDITIONAL_IGNORE) { return false; } if(elementType == XmlElementType.XML_ENTITY_REF) { XmlEntityRef xmlEntityRef = (XmlEntityRef) child.getPsi(); final String text = xmlEntityRef.getText(); String name = text.substring(1, text.length() - 1); PsiElement psiElement = targetFile != null ? XmlEntityCache.getCachedEntity(targetFile, name) : null; if(psiElement instanceof XmlEntityDecl) { final XmlEntityDecl decl = (XmlEntityDecl) psiElement; if(decl.isInternalReference()) { for(ASTNode e = decl.getNode().getFirstChildNode(); e != null; e = e.getTreeNext()) { if(e.getElementType() == XmlElementType.XML_ATTRIBUTE_VALUE) { final boolean b = StringUtil.stripQuotesAroundValue(e.getText()).equals("INCLUDE"); return b; } } } } } } } return false; }
@Override public boolean canFindUsagesFor(@NotNull PsiElement element) { return element instanceof XmlElementDecl || element instanceof XmlAttributeDecl || element instanceof XmlEntityDecl || element instanceof XmlTag || element instanceof XmlAttributeValue || element instanceof PsiFile || element instanceof XmlComment; }