remove unused code and restore 'change context' fix for unresolved ant tags

This commit is contained in:
Eugene Zhuravlev
2012-06-24 01:04:09 +02:00
parent b90770b32a
commit 242527187b
117 changed files with 195 additions and 11259 deletions
+3 -9
View File
@@ -24,20 +24,14 @@
<packaging.artifactPropertiesProvider implementation="com.intellij.lang.ant.config.impl.artifacts.AntArtifactPostprocessingPropertiesProvider"/>
<packaging.artifactPropertiesProvider implementation="com.intellij.lang.ant.config.impl.artifacts.AntArtifactPreProcessingPropertiesProvider"/>
<keymapExtension implementation="com.intellij.lang.ant.config.impl.AntKeymapExtension"/>
<extendWordSelectionHandler implementation="com.intellij.lang.ant.AntPropertyRefSelectioner"/>
<highlightRangeExtension implementation="com.intellij.lang.ant.AntHighlightRangeExtension"/>
<vetoRenameCondition implementation="com.intellij.lang.ant.refactoring.AntVetoRenameCondition"/>
<renamePsiElementProcessor implementation="com.intellij.lang.ant.dom.AntRenameProcessor"/>
<daemon.externalAnnotatorsFilter implementation="com.intellij.lang.ant.validation.AntAnnotatorsFilter"/>
<!--<xml.fileNSInfoProvider implementation="com.intellij.lang.ant.AntDefaultNSProvider"/>-->
<lang.documentationProvider language="XML" implementationClass="com.intellij.lang.ant.doc.AntDomDocumentationProvider"/>
<breadcrumbsInfoProvider implementation="com.intellij.lang.ant.config.impl.AntBreadcrumbsInfoProvider"/>
<fileBasedIndex implementation="com.intellij.lang.ant.psi.impl.AntImportsIndex"/>
<fileBasedIndex implementation="com.intellij.lang.ant.AntImportsIndex"/>
<codeInsight.unresolvedReferenceQuickFixProvider implementation="com.intellij.lang.ant.quickfix.AntUnresolvedRefsFixProvider"/>
<hectorComponentProvider implementation="com.intellij.lang.ant.validation.AntHectorPanelProvider"/>
<declarationRangeHandler key="com.intellij.lang.ant.psi.AntStructuredElement"
implementationClass="com.intellij.lang.ant.AntDeclarationRangeHandler"/>
<refactoring.elementListenerProvider implementation="com.intellij.lang.ant.refactoring.AntTargetRenameListenerProvider"/>
<localInspection language="XML" shortName="AntDuplicateTargetsInspection" bundle="messages.AntBundle" key="ant.duplicate.targets.inspection"
groupKey="ant.inspections.display.name" enabledByDefault="true" level="ERROR"
@@ -45,7 +39,7 @@
<localInspection language="XML" shortName="AntMissingPropertiesFileInspection" bundle="messages.AntBundle" key="ant.missing.properties.file.inspection"
groupKey="ant.inspections.display.name" enabledByDefault="true" level="ERROR"
implementationClass="com.intellij.lang.ant.validation.AntMissingPropertiesFileInspection"/>
<localInspection language="XML" shortName="AntResolveInspection" displayName="Reference resolve problems" bundle="messages.AntBundle"
<localInspection language="XML" shortName="AntResolveInspection" displayName="Ant references resolve problems" bundle="messages.AntBundle"
groupKey="ant.inspections.display.name"
enabledByDefault="true" level="ERROR" implementationClass="com.intellij.lang.ant.dom.AntResolveInspection"/>
@@ -1,34 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant;
import com.intellij.codeInsight.hint.DeclarationRangeHandler;
import com.intellij.codeInsight.hint.DeclarationRangeUtil;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
/**
* @author yole
*/
public class AntDeclarationRangeHandler implements DeclarationRangeHandler {
@NotNull
public TextRange getDeclarationRange(@NotNull final PsiElement container) {
AntStructuredElement element = (AntStructuredElement) container;
return DeclarationRangeUtil.getDeclarationRange(element.getSourceElement());
}
}
@@ -1,56 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant;
import com.intellij.lang.ant.config.AntConfigurationBase;
import com.intellij.lang.ant.psi.impl.AntFileImpl;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlFileNSInfoProvider;
import com.intellij.psi.xml.XmlTag;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
/**
* @author Maxim.Mossienko, lvo
*/
public class AntDefaultNSProvider implements XmlFileNSInfoProvider {
@NonNls
private static final String ANT_URI = "http://ant.apache.org/schema.xsd"; // XmlUtil.ANT_URI
private static final String[][] myNamespaces = new String[][]{new String[]{"", ANT_URI}};
// nsPrefix, namespaceId
public String[][] getDefaultNamespaces(@NotNull XmlFile xmlFile) {
if (AntConfigurationBase.getInstance(xmlFile.getProject()).getAntBuildFile(xmlFile) != null) {
return myNamespaces;
}
final XmlDocument document = xmlFile.getDocument();
if (document != null) {
final XmlTag tag = document.getRootTag();
if (tag != null && AntFileImpl.PROJECT_TAG.equals(tag.getName()) && tag.getContext() instanceof XmlDocument) {
if (tag.getAttributeValue(AntFileImpl.DEFAULT_ATTR) != null) {
return myNamespaces;
}
final VirtualFile file = xmlFile.getVirtualFile();
if (file != null && ForcedAntFileAttribute.isAntFile(file)) {
return myNamespaces;
}
}
}
return null;
}
}
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.lang.ant.psi;
package com.intellij.lang.ant;
import org.jetbrains.annotations.NotNull;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.lang.ant.psi.impl;
package com.intellij.lang.ant;
import com.intellij.ide.highlighter.XmlFileType;
import com.intellij.openapi.vfs.VirtualFile;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.lang.ant.psi.impl;
package com.intellij.lang.ant;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.Alarm;
@@ -32,7 +32,7 @@ import java.util.*;
* Date: Mar 22, 2007
*/
public final class AntIntrospector {
private static final Logger LOG = Logger.getInstance("#com.intellij.lang.ant.psi.impl.AntIntrospector");
private static final Logger LOG = Logger.getInstance("#com.intellij.lang.ant.AntIntrospector");
private final Object myHelper;
//private static final ObjectCache<String, SoftReference<Object>> ourCache = new ObjectCache<String, SoftReference<Object>>(300);
private static final HashMap<Class, Object> ourCache = new HashMap<Class, Object>();
@@ -1,57 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageFilter;
import com.intellij.lang.ant.psi.impl.AntFileImpl;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
public class AntLanguageExtension implements LanguageFilter {
public boolean isRelevantForFile(final PsiFile psi) {
if (psi instanceof XmlFile) {
if (isAntFile((XmlFile)psi)) return true;
}
return false;
}
public static boolean isAntFile(final XmlFile xmlFile) {
final XmlDocument document = xmlFile.getDocument();
if (document != null) {
final XmlTag tag = document.getRootTag();
if (tag != null && AntFileImpl.PROJECT_TAG.equals(tag.getName()) && tag.getContext() instanceof XmlDocument) {
if (tag.getAttributeValue(AntFileImpl.DEFAULT_ATTR) != null) {
return true;
}
VirtualFile vFile = xmlFile.getOriginalFile().getVirtualFile();
if (vFile != null && ForcedAntFileAttribute.isAntFile(vFile)) {
return true;
}
}
}
return false;
}
public Language getLanguage() {
return AntSupport.getLanguage();
}
}
@@ -1,78 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant;
import com.intellij.lang.*;
import com.intellij.lang.ant.psi.impl.AntFileImpl;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.project.Project;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.tree.IFileElementType;
import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull;
public class AntParserDefinition implements ParserDefinition {
private final ParserDefinition myXmlParserDef;
public AntParserDefinition() {
myXmlParserDef = LanguageParserDefinitions.INSTANCE.forLanguage(StdLanguages.XML);
}
@NotNull
public Lexer createLexer(Project project) {
return myXmlParserDef.createLexer(project);
}
@NotNull
public PsiParser createParser(Project project) {
return myXmlParserDef.createParser(project);
}
public IFileElementType getFileNodeType() {
return myXmlParserDef.getFileNodeType();
}
@NotNull
public TokenSet getWhitespaceTokens() {
return myXmlParserDef.getWhitespaceTokens();
}
@NotNull
public TokenSet getCommentTokens() {
return myXmlParserDef.getCommentTokens();
}
@NotNull
public TokenSet getStringLiteralElements() {
return TokenSet.EMPTY;
}
@NotNull
public PsiElement createElement(ASTNode node) {
return myXmlParserDef.createElement(node);
}
public PsiFile createFile(FileViewProvider viewProvider) {
return new AntFileImpl(viewProvider);
}
public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) {
return SpaceRequirements.MAY;
}
}
@@ -1,82 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant;
import com.intellij.codeInsight.editorActions.ExtendWordSelectionHandler;
import com.intellij.lang.ant.psi.AntFile;
import com.intellij.lang.ant.psi.impl.reference.AntPropertyReference;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
/**
* @author Eugene Zhuravlev
* Date: Sep 14, 2007
*/
public class AntPropertyRefSelectioner implements ExtendWordSelectionHandler {
public boolean canSelect(final PsiElement e) {
return getRangesToSelect(e).size() > 0;
}
public List<TextRange> select(final PsiElement e, final CharSequence editorText, final int cursorOffset, final Editor editor) {
List<TextRange> rangesToSelect = getRangesToSelect(e);
for (Iterator it = rangesToSelect.iterator(); it.hasNext();) {
final TextRange range = (TextRange)it.next();
if (!range.contains(cursorOffset)) {
it.remove();
}
}
return rangesToSelect;
}
@NotNull
private static List<TextRange> getRangesToSelect(PsiElement e) {
final PsiFile containingFile = e.getContainingFile();
if (containingFile == null) {
return Collections.emptyList();
}
final AntFile antFile = AntSupport.getAntFile(containingFile);
if (antFile == null) {
return Collections.emptyList();
}
final PsiElement antElement = antFile.findElementAt(e.getTextOffset());
if (antElement == null) {
return Collections.emptyList();
}
final TextRange antElementRange = antElement.getTextRange();
final TextRange selectionElementRange = e.getTextRange();
final PsiReference[] refs = antElement.getReferences();
ArrayList<TextRange> ranges = new ArrayList<TextRange>(refs.length);
for (PsiReference ref : refs) {
if (ref instanceof AntPropertyReference) {
TextRange refRange = ref.getRangeInElement();
refRange = refRange.shiftRight(antElementRange.getStartOffset());
if (selectionElementRange.contains(refRange)) {
ranges.add(refRange);
}
}
}
return ranges;
}
}
@@ -1,99 +0,0 @@
/*
* Copyright 2000-2009 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.
*/
/*
* @author max
*/
package com.intellij.lang.ant;
import com.intellij.ide.structureView.*;
import com.intellij.ide.structureView.impl.common.PsiTreeElementBase;
import com.intellij.ide.util.treeView.smartTree.Sorter;
import com.intellij.lang.PsiStructureViewFactory;
import com.intellij.lang.ant.psi.AntFile;
import com.intellij.lang.ant.psi.AntProject;
import com.intellij.lang.ant.psi.AntTarget;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class AntStructureViewBuilderFactory implements PsiStructureViewFactory {
public static final String UNNAMED = AntBundle.message("unnamed.string.presentation");
@Nullable
public StructureViewBuilder getStructureViewBuilder(PsiFile psiFile) {
final AntFile antFile = AntSupport.getAntFile(psiFile);
if (antFile != null ) {
return new TreeBasedStructureViewBuilder() {
@NotNull
public StructureViewModel createStructureViewModel() {
return new StructureViewModelBase(antFile, new AntFileTreeElement(antFile))
.withSuitableClasses(AntFile.class, AntTarget.class);
}
};
}
return null;
}
static class AntFileTreeElement extends PsiTreeElementBase<AntFile> {
public AntFileTreeElement(AntFile antFile) {
super(antFile);
}
private AntProject getAntProject() {
return getValue().getAntProject();
}
public String getPresentableText() {
final String name = getAntProject().getName();
return name != null ? name : UNNAMED;
}
@NotNull
public Collection<StructureViewTreeElement> getChildrenBase() {
List<StructureViewTreeElement> list = new ArrayList<StructureViewTreeElement>();
for (AntTarget target : getAntProject().getTargets()) {
list.add(new AntTargetTreeElement(target));
}
Collections.sort(list, Sorter.ALPHA_SORTER.getComparator());
return list;
}
}
static class AntTargetTreeElement extends PsiTreeElementBase<AntTarget> {
public AntTargetTreeElement(AntTarget target) {
super(target);
}
public String getPresentableText() {
final AntTarget value = getValue();
final String name = value != null? value.getName() : null;
return name != null ? name : UNNAMED;
}
@NotNull
public Collection<StructureViewTreeElement> getChildrenBase() {
return new ArrayList<StructureViewTreeElement>();
}
}
}
@@ -19,11 +19,8 @@ import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.lang.ant.dom.AntDomAntlib;
import com.intellij.lang.ant.dom.AntDomElement;
import com.intellij.lang.ant.dom.AntDomProject;
import com.intellij.lang.ant.psi.AntFile;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
@@ -40,26 +37,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Collections;
import java.util.List;
public class AntSupport implements ApplicationComponent {
private static LanguageFileType ourFileType = null;
private static AntLanguage ourLanguage = null;
public AntSupport(FileTypeManager fileTypeManager) {
//fileTypeManager.getRegisteredFileTypes();
//((CompositeLanguage)StdLanguages.XML).registerLanguageExtension(new AntLanguageExtension());
}
public static synchronized AntLanguage getLanguage() {
if (ourLanguage == null) {
if (ourFileType == null) {
ourFileType = new AntFileType();
}
ourLanguage = (AntLanguage)ourFileType.getLanguage();
}
return ourLanguage;
public AntSupport() {
}
@NotNull
@@ -101,24 +82,6 @@ public class AntSupport implements ApplicationComponent {
// Managing ant files dependencies via the <import> task.
//
public static synchronized List<AntFile> getImportingFiles(final AntFile imported) {
// todo: to be removed soon
return Collections.emptyList();
}
public static synchronized void registerDependency(final AntFile importing, final AntFile imported) {
// todo: to be removed soon
}
public static AntFile getAntFile ( PsiFile psiFile ) {
if (psiFile instanceof AntFile) {
return (AntFile)psiFile;
}
else {
return (AntFile)psiFile.getViewProvider().getPsi(getLanguage());
}
}
@Nullable
public static AntDomProject getAntDomProject(PsiFile psiFile) {
if (psiFile instanceof XmlFile) {
@@ -1,26 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant;
import com.intellij.psi.PsiElement;
/**
* @author dyoma
*/
public interface PsiAntElement extends PsiElement {
AntElementRole getRole();
boolean canRename();
}
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.lang.ant.psi.impl;
package com.intellij.lang.ant;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
@@ -35,7 +35,7 @@ import java.util.concurrent.locks.ReentrantLock;
* Date: Apr 9, 2010
*/
public final class ReflectedProject {
private static final Logger LOG = Logger.getInstance("#com.intellij.lang.ant.psi.impl.ReflectedProject");
private static final Logger LOG = Logger.getInstance("#com.intellij.lang.ant.ReflectedProject");
@NonNls private static final String INIT_METHOD_NAME = "init";
@NonNls private static final String GET_TASK_DEFINITIONS_METHOD_NAME = "getTaskDefinitions";
@@ -31,6 +31,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.xml.DomElement;
@@ -85,26 +86,43 @@ public class RunTargetAction extends AnAction {
final Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
final Project project = PlatformDataKeys.PROJECT.getData(dataContext);
if (project == null || editor == null) return null;
if (project == null || editor == null) {
return null;
}
final VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext);
if (file == null) return null;
if (file == null) {
return null;
}
final PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
if (!(psiFile instanceof XmlFile)) return null;
final AntBuildFileBase antFile = AntConfigurationBase.getInstance(project).getAntBuildFile(psiFile);
if (antFile == null) return null;
if (!(psiFile instanceof XmlFile)) {
return null;
}
final XmlFile xmlFile = (XmlFile)psiFile;
PsiElement at = xmlFile.findElementAt(editor.getCaretModel().getOffset());
while (at != null && !(at instanceof XmlTag)) at = at.getParent();
if (at == null) return null;
DomElement dom = AntSupport.getAntDomElement((XmlTag)at);
while (dom != null && !(dom instanceof AntDomTarget)) dom = dom.getParent();
final AntBuildFileBase antFile = AntConfigurationBase.getInstance(project).getAntBuildFile(xmlFile);
if (antFile == null) {
return null;
}
final AntDomTarget tar = (AntDomTarget)dom;
if (tar == null) return null;
return Pair.create(antFile, tar);
final PsiElement element = xmlFile.findElementAt(editor.getCaretModel().getOffset());
if (element == null) {
return null;
}
final XmlTag xmlTag = PsiTreeUtil.getParentOfType(element, XmlTag.class);
if (xmlTag == null) {
return null;
}
DomElement dom = AntSupport.getAntDomElement(xmlTag);
while (dom != null && !(dom instanceof AntDomTarget)) {
dom = dom.getParent();
}
final AntDomTarget domTarget = (AntDomTarget)dom;
if (domTarget == null) {
return null;
}
return Pair.create(antFile, domTarget);
}
}
@@ -1,101 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.config.impl;
import com.intellij.lang.Language;
import com.intellij.lang.ant.AntSupport;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.lang.ant.psi.introspection.AntTypeId;
import com.intellij.psi.PsiElement;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.xml.breadcrumbs.BreadcrumbsInfoProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Eugene Zhuravlev
* Date: Jun 22, 2007
*/
public class AntBreadcrumbsInfoProvider extends BreadcrumbsInfoProvider {
private static final Language[] ourSupportedLanguages = new Language[] {AntSupport.getLanguage()};
public Language[] getLanguages() {
return ourSupportedLanguages;
}
public boolean acceptElement(@NotNull final PsiElement e) {
return e instanceof AntStructuredElement && e.isValid();
}
@NotNull
public String getElementInfo(@NotNull final PsiElement e) {
AntStructuredElement se = (AntStructuredElement)e;
final AntTypeDefinition typeDef = se.getTypeDefinition();
if (typeDef == null) {
return se.getSourceElement().getName();
}
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
final AntTypeId typeId = typeDef.getTypeId();
final String nsPrefix = typeId.getNamespacePrefix();
if (nsPrefix != null) {
builder.append(nsPrefix);
builder.append(":");
}
builder.append(typeId.getName());
final String name = se.getName();
if (name != null) {
builder.append(" ");
builder.append(name);
}
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
@Nullable
public String getElementTooltip(@NotNull final PsiElement e) {
final XmlTag tag = ((AntStructuredElement)e).getSourceElement();
final StringBuilder result = StringBuilderSpinAllocator.alloc();
try {
result.append("<");
result.append(tag.getName());
for (final XmlAttribute attrib : tag.getAttributes()) {
result.append(" ").append(attrib.getText());
}
if (tag.isEmpty()) {
result.append("/>");
}
else {
result.append(">...</");
result.append(tag.getName());
result.append(">");
}
return result.toString();
}
finally {
StringBuilderSpinAllocator.dispose(result);
}
}
}
@@ -15,12 +15,12 @@
*/
package com.intellij.lang.ant.doc;
import com.intellij.lang.ant.AntFilesProvider;
import com.intellij.lang.ant.AntSupport;
import com.intellij.lang.ant.config.impl.AntInstallation;
import com.intellij.lang.ant.dom.AntDomElement;
import com.intellij.lang.ant.dom.AntDomProject;
import com.intellij.lang.ant.dom.AntDomTarget;
import com.intellij.lang.ant.psi.AntFilesProvider;
import com.intellij.lang.documentation.DocumentationProvider;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
@@ -15,7 +15,7 @@
*/
package com.intellij.lang.ant.dom;
import com.intellij.lang.ant.psi.AntFilesProvider;
import com.intellij.lang.ant.AntFilesProvider;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.xml.Attribute;
@@ -15,8 +15,8 @@
*/
package com.intellij.lang.ant.dom;
import com.intellij.lang.ant.psi.impl.AntIntrospector;
import com.intellij.lang.ant.psi.impl.ReflectedProject;
import com.intellij.lang.ant.AntIntrospector;
import com.intellij.lang.ant.ReflectedProject;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
@@ -15,7 +15,7 @@
*/
package com.intellij.lang.ant.dom;
import com.intellij.lang.ant.psi.AntFilesProvider;
import com.intellij.lang.ant.AntFilesProvider;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.util.text.StringTokenizer;
import com.intellij.util.xml.Attribute;
@@ -15,7 +15,7 @@
*/
package com.intellij.lang.ant.dom;
import com.intellij.lang.ant.psi.AntFilesProvider;
import com.intellij.lang.ant.AntFilesProvider;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.xml.Attribute;
@@ -15,7 +15,7 @@
*/
package com.intellij.lang.ant.dom;
import com.intellij.lang.ant.psi.AntFilesProvider;
import com.intellij.lang.ant.AntFilesProvider;
import com.intellij.util.PathUtil;
import com.intellij.util.xml.Attribute;
import com.intellij.util.xml.GenericAttributeValue;
@@ -15,7 +15,7 @@
*/
package com.intellij.lang.ant.dom;
import com.intellij.lang.ant.psi.AntFilesProvider;
import com.intellij.lang.ant.AntFilesProvider;
import org.jetbrains.annotations.NotNull;
import java.io.File;
@@ -15,7 +15,7 @@
*/
package com.intellij.lang.ant.dom;
import com.intellij.lang.ant.psi.AntFilesProvider;
import com.intellij.lang.ant.AntFilesProvider;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.util.xml.Attribute;
import com.intellij.util.xml.Convert;
@@ -15,12 +15,12 @@
*/
package com.intellij.lang.ant.dom;
import com.intellij.lang.ant.ReflectedProject;
import com.intellij.lang.ant.config.AntConfigurationBase;
import com.intellij.lang.ant.config.impl.AntBuildFileImpl;
import com.intellij.lang.ant.config.impl.AntConfigurationImpl;
import com.intellij.lang.ant.config.impl.AntInstallation;
import com.intellij.lang.ant.config.impl.GlobalAntConfiguration;
import com.intellij.lang.ant.psi.impl.ReflectedProject;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
@@ -17,6 +17,7 @@ package com.intellij.lang.ant.dom;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.lang.ant.AntBundle;
import com.intellij.lang.ant.quickfix.AntChangeContextLocalFix;
import com.intellij.lang.ant.validation.AntInspection;
import com.intellij.psi.PsiPolyVariantReference;
import com.intellij.psi.PsiReference;
@@ -40,7 +41,7 @@ public class AntResolveInspection extends AntInspection {
@NotNull
public String getDisplayName() {
return "Reference resolve problems";
return "Ant references resolve problems";
}
@NotNull
@@ -100,18 +101,15 @@ public class AntResolveInspection extends AntInspection {
continue;
}
if (!isResolvable(ref)) {
holder.createProblem(domElement, ProblemHighlightType.LIKE_UNKNOWN_SYMBOL, antDomRef.getUnresolvedMessagePattern(), ref.getRangeInElement() /*todo add quickfixes*/);
holder.createProblem(domElement, ProblemHighlightType.LIKE_UNKNOWN_SYMBOL, antDomRef.getUnresolvedMessagePattern(), ref.getRangeInElement(), new AntChangeContextLocalFix());
if (ref instanceof AntDomFileReference) {
if (processed == null) {
processed = new HashSet<PsiReference>();
}
ContainerUtil.addAll(processed, ((AntDomFileReference)ref).getFileReferenceSet().getAllReferences());
}
//final IntentionAction[] intentionActions = antRef.getFixes();
//for (final IntentionAction action : intentionActions) {
// annotation.registerFix(action);
//}
}
}
}
@@ -15,10 +15,10 @@
*/
package com.intellij.lang.ant.dom;
import com.intellij.lang.ant.AntFilesProvider;
import com.intellij.lang.ant.AntSupport;
import com.intellij.lang.ant.ReflectedProject;
import com.intellij.lang.ant.config.impl.AntResourcesClassLoader;
import com.intellij.lang.ant.psi.AntFilesProvider;
import com.intellij.lang.ant.psi.impl.ReflectedProject;
import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.diagnostic.Logger;
@@ -1,45 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.misc;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntProject;
import org.jetbrains.annotations.Nullable;
public class AntPsiUtil {
private AntPsiUtil() {
}
/**
* Returns an element under Ant project which is an ancestor of the specified element.
* Returns null for AntProject and AntFile.
*/
@Nullable
public static AntElement getSubProjectElement(AntElement element) {
AntElement parent = element.getAntParent();
while (true) {
if (parent == null) {
element = null;
break;
}
if (parent instanceof AntProject) break;
element = parent;
parent = parent.getAntParent();
}
return element;
}
}
@@ -1,51 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.misc;
import com.intellij.psi.PsiElement;
import com.intellij.util.SpinAllocator;
import java.util.HashSet;
import java.util.Set;
public class PsiElementSetSpinAllocator {
private PsiElementSetSpinAllocator() {
}
private static class Creator implements SpinAllocator.ICreator<Set<PsiElement>> {
public Set<PsiElement> createInstance() {
return new HashSet<PsiElement>();
}
}
private static class Disposer implements SpinAllocator.IDisposer<Set<PsiElement>> {
public void disposeInstance(final Set<PsiElement> instance) {
instance.clear();
}
}
private static final SpinAllocator<Set<PsiElement>> myAllocator =
new SpinAllocator<Set<PsiElement>>(new Creator(), new Disposer());
public static Set<PsiElement> alloc() {
return myAllocator.alloc();
}
public static void dispose(Set<PsiElement> instance) {
myAllocator.dispose(instance);
}
}
@@ -1,52 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.misc;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement;
import com.intellij.util.SpinAllocator;
import java.util.HashSet;
import java.util.Set;
public class PsiElementWithValueSetSpinAllocator {
private PsiElementWithValueSetSpinAllocator() {
}
private static class Creator implements SpinAllocator.ICreator<Set<Pair<PsiElement, String>>> {
public Set<Pair<PsiElement, String>> createInstance() {
return new HashSet<Pair<PsiElement, String>>();
}
}
private static class Disposer implements SpinAllocator.IDisposer<Set<Pair<PsiElement, String>>> {
public void disposeInstance(final Set<Pair<PsiElement, String>> instance) {
instance.clear();
}
}
private static final SpinAllocator<Set<Pair<PsiElement, String>>> myAllocator =
new SpinAllocator<Set<Pair<PsiElement, String>>>(new Creator(), new Disposer());
public static Set<Pair<PsiElement, String>> alloc() {
return myAllocator.alloc();
}
public static void dispose(Set<Pair<PsiElement, String>> instance) {
myAllocator.dispose(instance);
}
}
@@ -1,23 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
/**
* An element which can contain all tasks as nested elements and nothing else.
* Is used to wrap the Sequential and Parallel tasks.
*/
public interface AntAllTasksContainer extends AntTask {
}
@@ -1,25 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.Nullable;
public interface AntAnt extends AntTask {
@Nullable
PsiFile getCalledAntFile();
}
@@ -1,28 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface AntCall extends AntTask {
@Nullable
AntTarget getTarget();
@NotNull
AntProperty[] getParams();
}
@@ -1,21 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
import com.intellij.psi.PsiComment;
public interface AntComment extends PsiComment, AntElement {
}
@@ -1,24 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
/**
* @author Eugene Zhuravlev
* Date: Aug 8, 2008
*/
public interface AntDefTask extends AntTask {
void clearClassesCache();
}
@@ -1,49 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
import com.intellij.lang.ant.PsiAntElement;
import com.intellij.psi.xml.XmlElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface AntElement extends PsiAntElement {
AntElement[] EMPTY_ARRAY = new AntElement[0];
XmlElement getSourceElement();
@Nullable
AntElement getAntParent();
AntFile getAntFile();
AntProject getAntProject();
void clearCaches();
/**
* Does the same as findElementAt() but without rebuilding cleared PSI.
*
* @param offset
* @return
*/
@Nullable
AntElement lightFindElementAt(int offset);
void incModificationCount();
void acceptAntElementVisitor(@NotNull final AntElementVisitor visitor);
}
@@ -1,82 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
import com.intellij.lang.ant.PsiAntElement;
import com.intellij.psi.PsiElement;
/**
* @author Eugene Zhuravlev
* Date: Apr 13, 2007
*/
public class AntElementVisitor {
public void visitAntElement(final PsiAntElement antElement) {
final PsiElement[] psiElements = antElement.getChildren();
for (PsiElement child : psiElements) {
if (child instanceof AntElement) {
((AntElement)child).acceptAntElementVisitor(this);
}
}
}
public void visitAntStructuredElement(final AntStructuredElement element) {
visitAntElement(element);
}
public void visitAntTarget(final AntTarget target) {
visitAntElement(target);
}
public void visitAntTask(final AntTask task) {
visitAntElement(task);
}
public void visitAntCall(final AntCall antCall) {
visitAntElement(antCall);
}
public void visitAntImport(final AntImport antImport) {
visitAntElement(antImport);
}
public void visitAntProperty(final AntProperty antProperty) {
visitAntElement(antProperty);
}
public void visitAntTypedef(final AntTypeDef typeDef) {
visitAntElement(typeDef);
}
public void visitAntMacroDef(final AntMacroDef antMacroDef) {
visitAntElement(antMacroDef);
}
public void visitAntScriptDef(final AntScriptDef antScriptDef) {
visitAntElement(antScriptDef);
}
public void visitAntPresetDef(final AntPresetDef presetDef) {
visitAntElement(presetDef);
}
public void visitAntProject(final AntProject antProject) {
visitAntElement(antProject);
}
public void visitAntFile(final AntFile antFile) {
visitAntElement(antFile);
}
}
@@ -1,85 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
import com.intellij.lang.ant.config.impl.AntInstallation;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.openapi.util.ModificationTracker;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.xml.XmlFile;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public interface AntFile extends PsiFile, AntElement, PsiNamedElement, ModificationTracker {
AntFile[] EMPTY_ARRAY = new AntFile[0];
@NotNull
XmlFile getSourceElement();
ClassLoader getClassLoader();
@Nullable
AntInstallation getAntInstallation();
@NotNull
AntTypeDefinition[] getBaseTypeDefinitions();
@Nullable
AntTypeDefinition getBaseTypeDefinition(final String taskClassName);
@Nullable /* will return null in case ant installation was not properly configured*/
AntTypeDefinition getTargetDefinition();
void registerCustomType(final AntTypeDefinition def);
void unregisterCustomType(final AntTypeDefinition def);
VirtualFile getVirtualFile();
void clearExternalProperties();
void setExternalProperty(@NotNull final String name, @NotNull final String value);
@Nullable
VirtualFile getContainingPath();
void clearCachesWithTypeDefinitions();
void addEnvironmentPropertyPrefix(@NotNull final String envPrefix);
boolean isEnvironmentProperty(@NotNull final String propName);
List<String> getEnvironmentPrefixes();
@Nullable
AntProperty getProperty(@NonNls final String name);
void processAllProperties(@NonNls final String name, Processor<AntProperty> processor);
void setProperty(final String name, final AntProperty element);
@NotNull
AntProperty[] getProperties();
void invalidateProperties();
}
@@ -1,27 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
import org.jetbrains.annotations.Nullable;
public interface AntImport extends AntTask {
@Nullable
String getFileName();
@Nullable
AntFile getImportedFile();
}
@@ -1,22 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
public interface AntMacroDef extends AntDefTask {
AntTypeDefinition getMacroDefinition();
}
@@ -1,29 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
/**
* @author Eugene Zhuravlev
* Date: Jun 20, 2007
*/
public interface AntNameIdentifier extends AntElement {
String getIdentifierName();
void setIdentifierName(@NotNull String name) throws IncorrectOperationException;
}
@@ -1,22 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
public interface AntPresetDef extends AntDefTask {
AntTypeDefinition getPresetDefinition();
}
@@ -1,51 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface AntProject extends AntStructuredElement {
@Nullable
String getBaseDir();
@Nullable
String getDescription();
@NotNull
AntTarget[] getTargets();
@Nullable
AntTarget getTarget(final String name);
@Nullable
AntTarget getDefaultTarget();
@NotNull
AntTarget[] getImportedTargets();
@NotNull
AntFile[] getImportedFiles();
void registerRefId(final String id, AntElement element);
@Nullable
AntElement getElementByRefId(String refid);
@NotNull
String[] getRefIds();
}
@@ -1,57 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
import com.intellij.lang.properties.psi.PropertiesFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
public interface AntProperty extends AntTask {
AntProperty[] EMPTY_ARRAY = new AntProperty[0];
@NonNls String TSTAMP_TAG = "tstamp";
@NonNls String TSTAMP_PATTERN_ATTRIBUTE_NAME = "pattern";
@NonNls String TSTAMP_TIMEZONE_ATTRIBUTE_NAME = "timezone";
/**
* Calculates property value.
*
* @param propName -- name of a property, some property elements may define several properties.
* @return
*/
@Nullable
String getValue(final String propName);
@Nullable
String getFileName();
@Nullable
PropertiesFile getPropertiesFile();
@Nullable
String getPrefix();
@Nullable
String getEnvironment();
@Nullable
String[] getNames();
@Nullable
AntElement getFormatElement(final String propName);
boolean isTstamp();
}
@@ -1,22 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
public interface AntScriptDef extends AntDefTask {
AntTypeDefinition getScriptDefinition();
}
@@ -1,81 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.xml.XmlTag;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public interface AntStructuredElement extends AntElement, PsiNamedElement {
@NotNull
XmlTag getSourceElement();
@Nullable
AntTypeDefinition getTypeDefinition();
void registerCustomType(final AntTypeDefinition def);
void unregisterCustomType(final AntTypeDefinition def);
boolean hasImportedTypeDefinition();
/**
* Finds psi file by specified name in the directory of current ant file.
*
* @param name - name of the file to find.
* @return psi file if it exists, else null.
*/
@Nullable
PsiFile findFileByName(final String name);
/**
* Finds psi file by specified name and basedir.
*
* @param name - name of the file to find.
* @param baseDir - base directory where to find the file. If the parameter is specified as null, ant project's base directory property is used.
* @return psi file if it exists, else null.
*/
@Nullable
PsiFile findFileByName(final String name, @Nullable final String baseDir);
@Nullable
String computeAttributeValue(@NonNls String value);
boolean hasNameElement();
boolean hasIdElement();
@NonNls
@NotNull
List<String> getFileReferenceAttributes();
/**
* @return true if is instance of a type defined by the <typedef> or <taskdef> task.
*/
boolean isTypeDefined();
/**
* @return true if is instance of a type defined by the <presetdef> task.
*/
boolean isPresetDefined();
}
@@ -1,57 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface AntTarget extends AntStructuredElement {
enum ConditionalAttribute {
IF("if"), UNLESS("unless");
private final String xmlName;
ConditionalAttribute(@NonNls final String xmlName) {
this.xmlName = xmlName;
}
public String getXmlName() {
return xmlName;
}
}
AntTarget[] EMPTY_ARRAY = new AntTarget[0];
/**
* @return If project is named, target name prefixed with project name and the dot,
* otherwise target name equal to that returned by {@link #getName()}.
*/
@NotNull
String getQualifiedName();
@Nullable
String getDescription();
@NotNull
AntTarget[] getDependsTargets();
@Nullable
String getConditionalPropertyName(ConditionalAttribute attrib);
void setDependsTargets(@NotNull AntTarget[] targets);
}
@@ -1,23 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
public interface AntTask extends AntStructuredElement {
boolean isMacroDefined();
boolean isScriptDefined();
}
@@ -1,60 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface AntTypeDef extends AntDefTask {
@Nullable
String getDefinedName();
@Nullable
String getClassName();
@Nullable
String getClassPath();
@Nullable
String getUri();
@Nullable
String getFile();
@Nullable
String getResource();
@NonNls
@Nullable
String getFormat();
@NotNull
AntTypeDefinition[] getDefinitions();
boolean typesLoaded();
@Nullable
String getLocalizedError();
@Nullable
String getAdapterName();
@Nullable
String getAdaptToName();
}
@@ -1,53 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.psi.AntAllTasksContainer;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.StringBuilderSpinAllocator;
import org.jetbrains.annotations.NonNls;
public class AntAllTasksContainerImpl extends AntTaskImpl implements AntAllTasksContainer {
public AntAllTasksContainerImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition) {
super(parent, sourceElement, definition);
/*
if (myDefinition != null && definition != null && myDefinition.getNestedClassName(definition.getTypeId()) == null) {
// allow all tasks as nested elements
for (final AntTypeDefinition def : getAntFile().getBaseTypeDefinitions()) {
if (def.isTask()) {
myDefinition.registerNestedType(def.getTypeId(), def.getClassName());
}
}
}
*/
}
public String toString() {
@NonNls final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append("AntAllTasksContainer[");
builder.append(getSourceElement().getName());
builder.append("]");
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
}
@@ -1,91 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.psi.AntAnt;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.impl.reference.AntTargetReference;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.StringBuilderSpinAllocator;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class AntAntImpl extends AntTaskImpl implements AntAnt {
@NonNls private static final String DEFAULT_ANTFILE = "build.xml";
public AntAntImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition) {
super(parent, sourceElement, definition);
}
public String toString() {
@NonNls final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append("Ant[");
builder.append(getFileName());
builder.append("]");
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
@NotNull
public List<String> getFileReferenceAttributes() {
final ArrayList<String> attribs = new ArrayList<String>(super.getFileReferenceAttributes());
attribs.add("antfile");
attribs.add("output");
return attribs;
}
@Nullable
public PsiFile getCalledAntFile() {
return findFileByName(getFileName(), getDir());
}
@NotNull
public PsiReference[] getReferences() {
final PsiReference[] result = super.getReferences();
for (final PsiReference reference : result) {
if (reference instanceof AntTargetReference) {
((AntTargetReference)reference).setShouldBeSkippedByAnnotator(getCalledAntFile() == null);
}
}
return result;
}
@NotNull
private String getFileName() {
final String result = getSourceElement().getAttributeValue("antfile");
if (result == null) {
return DEFAULT_ANTFILE;
}
return result;
}
@Nullable
private String getDir() {
return getSourceElement().getAttributeValue("dir");
}
}
@@ -1,104 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntFile;
import com.intellij.lang.ant.psi.AntProperty;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.StringBuilderSpinAllocator;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
public class AntBuildNumberImpl extends AntTaskImpl implements AntProperty {
@NonNls private static final String BUILD_NUMBER_PROPERTY = "build.number";
public AntBuildNumberImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition) {
super(parent, sourceElement, definition);
final AntFile antFile = getAntFile();
if (antFile != null) {
antFile.setProperty(BUILD_NUMBER_PROPERTY, this);
}
}
public String toString() {
@NonNls final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append("AntProperty[");
builder.append(getName());
builder.append("]");
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
public String getName() {
return BUILD_NUMBER_PROPERTY;
}
@NotNull
public List<String> getFileReferenceAttributes() {
return Collections.singletonList(AntFileImpl.FILE_ATTR);
}
@Nullable
public String getValue(final String propName) {
return null;
}
@Nullable
public String getFileName() {
return null;
}
@Nullable
public PropertiesFile getPropertiesFile() {
return null;
}
@Nullable
public String getPrefix() {
return null;
}
@Nullable
public String getEnvironment() {
return null;
}
@Nullable
public String[] getNames() {
return new String[]{getName()};
}
@Nullable
public AntElement getFormatElement(final String propName) {
return this;
}
public boolean isTstamp() {
return false;
}
}
@@ -1,106 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.psi.*;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.psi.PsiLock;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.StringBuilderSpinAllocator;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class AntCallImpl extends AntTaskImpl implements AntCall {
private AntTarget[] myDependsTargets = null;
private AntProperty[] myParams = null;
public AntCallImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition) {
super(parent, sourceElement, definition);
}
public void acceptAntElementVisitor(@NotNull final AntElementVisitor visitor) {
visitor.visitAntCall(this);
}
public String toString() {
@NonNls final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append("AntCall to ");
final AntTarget target = getTarget();
builder.append((target == null) ? "null" : target.toString());
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
@Nullable
public AntTarget getTarget() {
synchronized (PsiLock.LOCK) {
final String target = getSourceElement().getAttributeValue("target");
final AntTarget result = (target == null) ? null : getAntProject().getTarget(target);
if (result != null) {
result.setDependsTargets(getDependsTargets());
}
return result;
}
}
@NotNull
public AntProperty[] getParams() {
synchronized (PsiLock.LOCK) {
if (myParams == null) {
final List<AntProperty> properties = new ArrayList<AntProperty>();
for (AntElement element : getChildren()) {
if (element instanceof AntProperty) {
properties.add((AntProperty)element);
}
}
myParams = properties.toArray(new AntProperty[properties.size()]);
}
return myParams;
}
}
public void clearCaches() {
synchronized (PsiLock.LOCK) {
super.clearCaches();
myDependsTargets = null;
}
}
@NotNull
private AntTarget[] getDependsTargets() {
synchronized (PsiLock.LOCK) {
if (myDependsTargets == null) {
final List<AntTarget> targets = new ArrayList<AntTarget>();
for (AntElement element : getChildren()) {
if (element instanceof AntTarget) {
targets.add((AntTarget)element);
}
}
myDependsTargets = targets.toArray(new AntTarget[targets.size()]);
}
return myDependsTargets;
}
}
}
@@ -1,45 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.psi.AntComment;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.xml.XmlComment;
import com.intellij.psi.xml.XmlElement;
import org.jetbrains.annotations.NotNull;
public class AntCommentImpl extends AntElementImpl implements AntComment {
public AntCommentImpl(final AntStructuredElement parent, final XmlElement sourceElement) {
super(parent, sourceElement);
}
public IElementType getTokenType() {
return ((XmlComment) getSourceElement()).getTokenType();
}
@SuppressWarnings({"HardCodedStringLiteral"})
public String toString() {
return "AntComment";
}
@NotNull
public PsiReference[] getReferences() {
return PsiReference.EMPTY_ARRAY;
}
}
@@ -1,112 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntFilesProvider;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.StringBuilderSpinAllocator;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* @author Eugene Zhuravlev
* Date: May 4, 2007
*/
public class AntDirSetImpl extends AntFilesProviderImpl{
public AntDirSetImpl(final AntElement parent, final XmlTag sourceElement) {
super(parent, sourceElement);
}
public AntDirSetImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition, @NonNls final String nameElementAttribute) {
super(parent, sourceElement, definition, nameElementAttribute);
}
public AntDirSetImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition) {
super(parent, sourceElement, definition);
}
@NotNull
protected List<File> getFiles(final AntPattern pattern, final Set<AntFilesProvider> processed) {
final File singleFile = getCanonicalFile(computeAttributeValue(getSourceElement().getAttributeValue("file")));
if (singleFile == null || pattern.hasIncludePatterns()) {
// if singleFile is specified, there are no implicit includes
final File root = getCanonicalFile(computeAttributeValue(getSourceElement().getAttributeValue("dir")));
if (root != null) {
final ArrayList<File> files = new ArrayList<File>();
if (singleFile != null && singleFile.isDirectory()) {
files.add(singleFile);
}
new FilesCollector().collectFiles(files, root, "", pattern);
return files;
}
}
if (singleFile != null && singleFile.isDirectory()) {
Collections.singletonList(singleFile);
}
return Collections.emptyList();
}
private static class FilesCollector {
private static final int MAX_DIRS_TO_PROCESS = 100;
private int myDirsProcessed = 0;
public void collectFiles(List<File> container, File from, String relativePath, final AntPattern pattern) {
if (myDirsProcessed > MAX_DIRS_TO_PROCESS) {
return;
}
myDirsProcessed++;
final File[] children = from.listFiles();
if (children != null) {
for (File child : children) {
if (child.isDirectory()) {
final String childPath = makePath(relativePath, child.getName());
if (pattern.acceptPath(childPath)) {
container.add(child);
}
if (pattern.couldBeIncluded(childPath)) {
collectFiles(container, child, childPath, pattern);
}
}
}
}
}
private static String makePath(final String parentPath, final String name) {
if (parentPath.length() == 0) {
return name;
}
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
return builder.append(parentPath).append("/").append(name).toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
}
}
@@ -1,348 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntFile;
import com.intellij.lang.ant.psi.AntProject;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.lang.ant.psi.introspection.AntTypeId;
import com.intellij.psi.PsiLock;
import com.intellij.psi.xml.XmlComment;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlEntityRef;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.containers.HashMap;
import org.apache.tools.ant.Target;
import org.apache.tools.ant.taskdefs.*;
import org.apache.tools.ant.taskdefs.optional.extension.JarLibResolveTask;
import org.apache.tools.ant.taskdefs.optional.perforce.P4Counter;
import org.apache.tools.ant.taskdefs.optional.script.ScriptDef;
import org.apache.tools.ant.types.DirSet;
import org.apache.tools.ant.types.FileList;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
public class AntElementFactory {
@NonNls private static final String RESULT_PROPERTY = "resultproperty";
@NonNls private static final String TOTAL_PROPERTY = "totalproperty";
private static Map<String, AntElementCreator> ourAntTypeToKnownAntElementCreatorMap = null;
private AntElementFactory() {
}
@Nullable
public static AntElement createAntElement(final AntStructuredElement parent, final XmlElement element) {
instantiate();
if (element instanceof XmlComment) {
return new AntCommentImpl(parent, element);
}
if (element instanceof XmlEntityRef) {
return new AntEntityRefImpl(parent, element);
}
if (!(element instanceof XmlTag)) return null;
final XmlTag tag = (XmlTag)element;
AntTypeDefinition typeDef = null;
String typeName = tag.getLocalName();
final String nsPrefix = tag.getNamespacePrefix();
if (nsPrefix.length() == 0 ) {
/**
* Hardcode for <javadoc> task (IDEADEV-6731).
*/
if (typeName.equals(AntFileImpl.JAVADOC2_TAG)) {
typeName = AntFileImpl.JAVADOC2_TAG;
}
/**
* Hardcode for <unwar> and <unjar> tasks (IDEADEV-6830).
*/
if (typeName.equals(AntFileImpl.UNWAR_TAG) || typeName.equals(AntFileImpl.UNJAR_TAG)) {
typeName = AntFileImpl.UNZIP_TAG;
}
}
final AntTypeId id = new AntTypeId(typeName, nsPrefix);
final AntFile file = parent.getAntFile();
final AntTypeDefinition parentDef = parent.getTypeDefinition();
if (parentDef != null) {
final String className = parentDef.getNestedClassName(id);
if (className != null && file != null) {
typeDef = file.getBaseTypeDefinition(className);
}
}
if (file != null) {
// try macrodef
if (typeDef == null) {
typeDef = file.getBaseTypeDefinition(AntMacroDefImpl.createMacroClassName(typeName));
}
// try preetDef
if (typeDef == null) {
typeDef = file.getBaseTypeDefinition(AntPresetDefImpl.createPresetDefClassName(typeName));
}
if (typeDef == null) {
final AntProject project = file.getAntProject();
final AntTypeDefinition projectDef = project != null? project.getTypeDefinition() : null;
for (AntTypeDefinition def : file.getBaseTypeDefinitions()) {
if (id.equals(def.getTypeId())) {
if (projectDef != null) { // perform additional check if project exists
final boolean isRegisteredWithinProject = def.getClassName().equals(projectDef.getNestedClassName(def.getTypeId()));
if (!isRegisteredWithinProject) {
continue;
}
}
typeDef = def;
break;
}
}
}
}
boolean importedType = false;
if (typeDef == null) {
final AntProject project = parent.getAntProject();
for (final AntFile imported : project.getImportedFiles()) {
final AntProject importedProject = imported.getAntProject();
if (!project.equals(importedProject)) {
importedProject.getChildren();
for (AntTypeDefinition def : imported.getBaseTypeDefinitions()) {
if (id.equals(def.getTypeId())) {
importedType = true;
typeDef = def;
break;
}
}
}
}
}
AntStructuredElementImpl result = null;
if (typeDef != null) {
final AntElementCreator antElementCreator = ourAntTypeToKnownAntElementCreatorMap.get(typeDef.getClassName());
if (antElementCreator != null) {
result = (AntStructuredElementImpl)antElementCreator.create(parent, tag);
}
else if (typeDef.isTask()) {
if (typeDef.isProperty()) {
result = new AntPropertyImpl(parent, tag, typeDef);
}
else if (typeDef.isAllTaskContainer()) {
result = new AntAllTasksContainerImpl(parent, tag, typeDef);
}
else {
result = new AntTaskImpl(parent, tag, typeDef);
}
}
}
if (result == null) {
// HACK for the <tstamp> properties
result = AntFileImpl.FORMAT_TAG.equals(tag.getName())
? new AntTimestampFormatImpl(parent, tag, typeDef)
: new AntStructuredElementImpl(parent, tag, typeDef);
}
result.setImportedTypeDefinition(importedType);
return result;
}
private static void instantiate() {
synchronized (PsiLock.LOCK) {
if (ourAntTypeToKnownAntElementCreatorMap == null) {
ourAntTypeToKnownAntElementCreatorMap = new HashMap<String, AntElementCreator>();
final AntElementCreator targetCreator = new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntTargetImpl(parent, tag);
}
};
ourAntTypeToKnownAntElementCreatorMap.put(Target.class.getName(), targetCreator);
ourAntTypeToKnownAntElementCreatorMap.put(Ant.TargetElement.class.getName(), targetCreator);
// properties
ourAntTypeToKnownAntElementCreatorMap.put(Property.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntPropertyImpl(parent, tag, parent.getAntFile().getBaseTypeDefinition(Property.class.getName()));
}
});
ourAntTypeToKnownAntElementCreatorMap.put(Tstamp.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntPropertyImpl(parent, tag, parent.getAntFile().getBaseTypeDefinition(Tstamp.class.getName()));
}
});
ourAntTypeToKnownAntElementCreatorMap.put(Checksum.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
final AntTypeDefinition checksumDef = parent.getAntFile().getBaseTypeDefinition(Checksum.class.getName());
if (tag.getAttributeValue(TOTAL_PROPERTY) != null) {
return new AntPropertyImpl(parent, tag, checksumDef, TOTAL_PROPERTY);
}
return new AntPropertyImpl(parent, tag, checksumDef, AntFileImpl.PROPERTY);
}
});
ourAntTypeToKnownAntElementCreatorMap.put(ExecTask.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
final AntTypeDefinition execDef = parent.getAntFile().getBaseTypeDefinition(ExecTask.class.getName());
if (tag.getAttributeValue(RESULT_PROPERTY) != null) {
return new AntPropertyImpl(parent, tag, execDef, RESULT_PROPERTY);
}
return new AntPropertyImpl(parent, tag, execDef, "outputproperty");
}
});
ourAntTypeToKnownAntElementCreatorMap.put(Java.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
final AntTypeDefinition execDef = parent.getAntFile().getBaseTypeDefinition(Java.class.getName());
return new AntPropertyImpl(parent, tag, execDef, RESULT_PROPERTY);
}
});
ourAntTypeToKnownAntElementCreatorMap.put(Input.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
final AntTypeDefinition execDef = parent.getAntFile().getBaseTypeDefinition(Input.class.getName());
return new AntPropertyImpl(parent, tag, execDef, "addproperty");
}
});
/*
ourAntTypeToKnownAntElementCreatorMap.put(Exit.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
final AntTypeDefinition failTaskDefinition = parent.getAntFile().getBaseTypeDefinition(Exit.class.getName());
if (tag.getAttributeValue(AntFileImpl.IF_ATTR) != null) {
return new AntPropertyImpl(parent, tag, failTaskDefinition, AntFileImpl.IF_ATTR);
}
return new AntPropertyImpl(parent, tag, failTaskDefinition, AntFileImpl.UNLESS_ATTR);
}
});
*/
for (final String clazz : PROPERTY_CLASSES) {
addPropertyCreator(clazz);
}
// sequential and parallel tasks can contain all other tasks
for (final String clazz : ALL_TASKS_CONTAINER_CLASSES) {
addAllTasksContainerCreator(clazz);
}
ourAntTypeToKnownAntElementCreatorMap.put(CallTarget.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntCallImpl(parent, tag, parent.getAntFile().getBaseTypeDefinition(CallTarget.class.getName()));
}
});
ourAntTypeToKnownAntElementCreatorMap.put(Taskdef.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntTypeDefImpl(parent, tag, parent.getAntFile().getBaseTypeDefinition(Taskdef.class.getName()));
}
});
ourAntTypeToKnownAntElementCreatorMap.put(Typedef.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntTypeDefImpl(parent, tag, parent.getAntFile().getBaseTypeDefinition(Typedef.class.getName()));
}
});
ourAntTypeToKnownAntElementCreatorMap.put(MacroDef.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntMacroDefImpl((AntStructuredElement)parent, tag,
parent.getAntFile().getBaseTypeDefinition(MacroDef.class.getName()));
}
});
ourAntTypeToKnownAntElementCreatorMap.put(PreSetDef.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntPresetDefImpl((AntStructuredElement)parent, tag,
parent.getAntFile().getBaseTypeDefinition(PreSetDef.class.getName()));
}
});
ourAntTypeToKnownAntElementCreatorMap.put(ScriptDef.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntScriptDefImpl((AntStructuredElement)parent, tag,
parent.getAntFile().getBaseTypeDefinition(ScriptDef.class.getName()));
}
});
ourAntTypeToKnownAntElementCreatorMap.put(ImportTask.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntImportImpl(parent, tag, parent.getAntFile().getBaseTypeDefinition(ImportTask.class.getName()));
}
});
ourAntTypeToKnownAntElementCreatorMap.put(Ant.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntAntImpl(parent, tag, parent.getAntFile().getBaseTypeDefinition(Ant.class.getName()));
}
});
ourAntTypeToKnownAntElementCreatorMap.put(BuildNumber.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntBuildNumberImpl(parent, tag, parent.getAntFile().getBaseTypeDefinition(BuildNumber.class.getName()));
}
});
ourAntTypeToKnownAntElementCreatorMap.put(DirSet.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntDirSetImpl(parent, tag, parent.getAntFile().getBaseTypeDefinition(DirSet.class.getName()));
}
});
ourAntTypeToKnownAntElementCreatorMap.put(FileList.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntFileListImpl(parent, tag, parent.getAntFile().getBaseTypeDefinition(FileList.class.getName()));
}
});
ourAntTypeToKnownAntElementCreatorMap.put(FileSet.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntFileSetImpl(parent, tag, parent.getAntFile().getBaseTypeDefinition(FileSet.class.getName()));
}
});
ourAntTypeToKnownAntElementCreatorMap.put(Path.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntPathImpl(parent, tag, parent.getAntFile().getBaseTypeDefinition(Path.class.getName()));
}
});
ourAntTypeToKnownAntElementCreatorMap.put(Path.PathElement.class.getName(), new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntPathImpl(parent, tag, parent.getAntFile().getBaseTypeDefinition(Path.PathElement.class.getName()));
}
});
}
}
}
private static void addPropertyCreator(final String className) {
ourAntTypeToKnownAntElementCreatorMap.put(className, new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntPropertyImpl(parent, tag, parent.getAntFile().getBaseTypeDefinition(className), AntFileImpl.PROPERTY);
}
});
}
private static void addAllTasksContainerCreator(final String className) {
ourAntTypeToKnownAntElementCreatorMap.put(className, new AntElementCreator() {
public AntStructuredElement create(final AntElement parent, final XmlTag tag) {
return new AntAllTasksContainerImpl(parent, tag, parent.getAntFile().getBaseTypeDefinition(className));
}
});
}
private final static String[] PROPERTY_CLASSES = {Available.class.getName(), ConditionTask.class.getName(), UpToDate.class.getName(),
Dirname.class.getName(), Basename.class.getName(), LoadFile.class.getName(), TempFile.class.getName(), PathConvert.class.getName(),
Length.class.getName(), WhichResource.class.getName(), JarLibResolveTask.class.getName(), P4Counter.class.getName(), ManifestClassPath.class.getName()};
private final static String[] ALL_TASKS_CONTAINER_CLASSES =
{MacroDef.NestedSequential.class.getName(), Sequential.class.getName(), Parallel.class.getName()};
private static interface AntElementCreator {
AntStructuredElement create(final AntElement parent, final XmlTag tag);
}
}
@@ -1,305 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.extapi.psi.MetadataPsiElementBase;
import com.intellij.lang.ASTNode;
import com.intellij.lang.ant.AntElementRole;
import com.intellij.lang.ant.AntLanguage;
import com.intellij.lang.ant.AntSupport;
import com.intellij.lang.ant.misc.PsiReferenceListSpinAllocator;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntElementVisitor;
import com.intellij.lang.ant.psi.AntFile;
import com.intellij.lang.ant.psi.AntProject;
import com.intellij.lang.ant.psi.impl.reference.AntReferenceProvidersRegistry;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.xml.XmlElement;
import com.intellij.util.ProcessingContext;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.List;
public class AntElementImpl extends MetadataPsiElementBase implements AntElement {
protected static final AntElement ourNull = new AntElementImpl(null, null) {
@NonNls
public String getName() {
return "AntNull";
}
public boolean isValid() {
return true;
}
};
private final AntElement myParent;
private volatile AntElement[] myChildren;
private volatile PsiReference[] myReferences;
private volatile PsiElement myPrev;
private volatile PsiElement myNext;
public AntElementImpl(final AntElement parent, final XmlElement sourceElement) {
super(sourceElement);
myParent = parent;
}
@NotNull
public AntLanguage getLanguage() {
return AntSupport.getLanguage();
}
public XmlElement getSourceElement() {
return (XmlElement)super.getSourceElement();
}
public String toString() {
@NonNls final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append("AntElement[");
builder.append(this == ourNull ? "null" : getSourceElement().toString());
builder.append("]");
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
@Nullable
public AntElement getAntParent() {
return myParent;
}
public AntProject getAntProject() {
PsiElement element = this;
while (!(element instanceof AntProject)) {
if (element == null || element instanceof PsiFile ) {
return null;
}
element = element.getParent();
}
return (AntProject)element;
}
public AntFile getAntFile() {
PsiElement element = getParent();
while (!(element instanceof AntFile)) {
if (element == null || element instanceof PsiFile ) {
return null;
}
element = element.getParent();
}
return (AntFile)element;
}
public AntElement getParent() {
return myParent;
}
@NotNull
public AntElement[] getChildren() {
synchronized (PsiLock.LOCK) {
if (myChildren == null) {
final AntFileImpl antFile = (AntFileImpl)getAntFile();
if (antFile != null) {
antFile.buildPropertiesIfNeeded();
}
}
if (myChildren != null) {
return myChildren;
}
return myChildren = getChildrenInner();
}
}
@Nullable
public AntElement getFirstChild() {
final AntElement[] children = getChildren();
return children.length == 0 ? null : children[0];
}
@Nullable
public PsiElement getLastChild() {
final PsiElement[] children = getChildren();
return children.length == 0 ? null : children[children.length - 1];
}
@Nullable
public PsiElement getNextSibling() {
if (myNext == null) {
final PsiElement parent = getAntParent();
if (parent != null) {
PsiElement temp = null;
for (final PsiElement element : parent.getChildren()) {
if (temp != null) {
myNext = element;
break;
}
if (element == this) {
temp = element;
}
}
}
}
return myNext;
}
@Nullable
public PsiElement getPrevSibling() {
if (myPrev == null) {
PsiElement prev = null;
final PsiElement parent = getAntParent();
if (parent != null) {
for (final PsiElement element : parent.getChildren()) {
if (element == this) {
break;
}
prev = element;
}
}
myPrev = prev;
}
return myPrev;
}
public void clearCaches() {
synchronized (PsiLock.LOCK) {
myChildren = null;
myReferences = null;
myPrev = null;
myNext = null;
incModificationCount();
}
}
public void incModificationCount() {
getAntFile().incModificationCount();
}
@Nullable
public AntElement lightFindElementAt(int offset) {
synchronized (PsiLock.LOCK) {
if (myChildren == null) {
return this;
}
final TextRange ownRange = getTextRange();
final int offsetInFile = offset + ownRange.getStartOffset();
for (final AntElement element : getChildren()) {
final TextRange textRange = element.getTextRange();
if (textRange.contains(offsetInFile)) {
return element.lightFindElementAt(offsetInFile - textRange.getStartOffset());
}
}
return ownRange.contains(offsetInFile) ? this : null;
}
}
public PsiElement findElementAt(int offset) {
if (!isValid()) {
return null;
}
final TextRange ownRange = getTextRange();
final int offsetInFile = offset + ownRange.getStartOffset();
for (final AntElement element : getChildren()) {
final TextRange textRange = element.getTextRange();
if (textRange.contains(offsetInFile)) {
PsiElement elementAt = element.findElementAt(offsetInFile - textRange.getStartOffset());
assert elementAt == null || elementAt.isValid() : element + ": " + offset;
return elementAt;
}
}
return ownRange.contains(offsetInFile)? this : null;
}
public ASTNode getNode() {
return null;
}
@NotNull
public PsiReference[] getReferences() {
if (myReferences != null) {
return myReferences;
}
final PsiReferenceProvider[] providers = AntReferenceProvidersRegistry.getProvidersByElement(this);
final List<PsiReference> result = PsiReferenceListSpinAllocator.alloc();
try {
for (final PsiReferenceProvider provider : providers) {
ContainerUtil.addAll(result, provider.getReferencesByElement(this, new ProcessingContext()));
}
return myReferences = result.toArray(new PsiReference[result.size()]);
}
finally {
PsiReferenceListSpinAllocator.dispose(result);
}
}
public AntElementRole getRole() {
return AntElementRole.NULL_ROLE;
}
public boolean canRename() {
return isPhysical();
}
public boolean isPhysical() {
return getSourceElement().isPhysical();
}
public boolean isValid() {
return getSourceElement().isValid();
}
PsiManager myCachedManager;
public PsiManager getManager() {
PsiManager manager = myCachedManager;
if (manager == null) {
manager = getSourceElement().getManager();
myCachedManager = manager;
}
return manager;
}
protected AntElement[] getChildrenInner() {
return AntElement.EMPTY_ARRAY;
}
public void acceptAntElementVisitor(@NotNull final AntElementVisitor visitor) {
visitor.visitAntElement(this);
}
protected AntElement clone() {
final AntElementImpl element = (AntElementImpl)super.clone();
element.clearCaches();
return element;
}
public Icon getElementIcon(int flags) {
return getRole().getIcon();
}
}
@@ -1,61 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.misc.PsiReferenceListSpinAllocator;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.lang.ant.psi.impl.reference.AntEntityReference;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiLock;
import com.intellij.psi.xml.XmlElement;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class AntEntityRefImpl extends AntElementImpl {
private PsiReference[] myRefs;
public AntEntityRefImpl(final AntStructuredElement parent, final XmlElement sourceElement) {
super(parent, sourceElement);
}
public void clearCaches() {
synchronized (PsiLock.LOCK) {
super.clearCaches();
myRefs = null;
}
}
@NotNull
public PsiReference[] getReferences() {
synchronized (PsiLock.LOCK) {
if (myRefs == null) {
final List<PsiReference> refList = PsiReferenceListSpinAllocator.alloc();
try {
for (final PsiReference ref : getSourceElement().getReferences()) {
refList.add(new AntEntityReference(this, ref));
}
myRefs = refList.toArray(new PsiReference[refList.size()]);
}
finally {
PsiReferenceListSpinAllocator.dispose(refList);
}
}
return myRefs;
}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,85 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntFilesProvider;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.psi.xml.XmlTag;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.*;
/**
* @author Eugene Zhuravlev
* Date: May 4, 2007
*/
public class AntFileListImpl extends AntFilesProviderImpl{
public AntFileListImpl(final AntElement parent, final XmlTag sourceElement) {
super(parent, sourceElement);
}
public AntFileListImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition, @NonNls final String nameElementAttribute) {
super(parent, sourceElement, definition, nameElementAttribute);
}
public AntFileListImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition) {
super(parent, sourceElement, definition);
}
protected AntPattern getPattern() {
return null; // not available for this data type
}
@NotNull
protected List<File> getFiles(final AntPattern pattern, final Set<AntFilesProvider> processed) {
final File root = getCanonicalFile(computeAttributeValue(getSourceElement().getAttributeValue("dir")));
if (root == null) {
return Collections.emptyList();
}
final ArrayList<File> files = new ArrayList<File>();
final String filenames = getSourceElement().getAttributeValue("files");
if (filenames != null) {
final StringTokenizer tokenizer = new StringTokenizer(filenames, ", \t\n\r\f", false);
while (tokenizer.hasMoreTokens()) {
files.add(new File(root, tokenizer.nextToken()));
}
}
final AntElement[] children = getChildren();
final AntTypeDefinition selfTypeDef = getTypeDefinition();
if (selfTypeDef != null) {
for (AntElement child : children) {
if (child instanceof AntStructuredElement) {
final AntStructuredElement se = (AntStructuredElement)child;
final AntTypeDefinition typeDef = se.getTypeDefinition();
if (typeDef != null && selfTypeDef.getNestedClassName(typeDef.getTypeId()) != null) {
final String fileName = computeAttributeValue(se.getSourceElement().getAttributeValue("name"));
if (fileName != null) {
files.add(new File(root, fileName));
}
}
}
}
}
return files;
}
}
@@ -1,115 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntFilesProvider;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.StringBuilderSpinAllocator;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* @author Eugene Zhuravlev
* Date: May 4, 2007
*/
public class AntFileSetImpl extends AntFilesProviderImpl{
public AntFileSetImpl(final AntElement parent, final XmlTag sourceElement) {
super(parent, sourceElement);
}
public AntFileSetImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition, @NonNls final String nameElementAttribute) {
super(parent, sourceElement, definition, nameElementAttribute);
}
public AntFileSetImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition) {
super(parent, sourceElement, definition);
}
@NotNull
protected List<File> getFiles(final AntPattern pattern, final Set<AntFilesProvider> processed) {
final File singleFile = getCanonicalFile(computeAttributeValue(getSourceElement().getAttributeValue("file")));
if (singleFile == null || pattern.hasIncludePatterns()) {
// if singleFile is specified, there are no implicit includes
final File root = getCanonicalFile(computeAttributeValue(getSourceElement().getAttributeValue("dir")));
if (root != null) {
final ArrayList<File> files = new ArrayList<File>();
if (singleFile != null) {
files.add(singleFile);
}
new FilesCollector().collectFiles(files, root, "", pattern);
return files;
}
}
if (singleFile != null) {
return Collections.singletonList(singleFile);
}
return Collections.emptyList();
}
private static class FilesCollector {
private static final int MAX_DIRS_TO_PROCESS = 100;
private int myDirsProcessed = 0;
private boolean myDirCheckEnabled = false;
public void collectFiles(List<File> container, File from, String relativePath, final AntPattern pattern) {
if (myDirsProcessed > MAX_DIRS_TO_PROCESS) {
return;
}
final File[] children = from.listFiles();
if (children != null && children.length > 0) {
if (myDirCheckEnabled) {
if (!pattern.couldBeIncluded(relativePath)) {
return;
}
}
else {
myDirCheckEnabled = true;
}
myDirsProcessed++;
for (File child : children) {
final String childPath = makePath(relativePath, child.getName());
if (pattern.acceptPath(childPath)) {
container.add(child);
}
collectFiles(container, child, childPath, pattern);
}
}
}
private static String makePath(final String parentPath, final String name) {
if (parentPath.length() == 0) {
return name;
}
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
return builder.append(parentPath).append("/").append(name).toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
}
}
@@ -1,162 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntFilesProvider;
import com.intellij.lang.ant.psi.impl.reference.AntRefIdReference;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiLock;
import com.intellij.psi.PsiReference;
import com.intellij.psi.xml.XmlTag;
import com.intellij.reference.SoftReference;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* @author Eugene Zhuravlev
* Date: May 4, 2007
*/
public class AntFilesProviderImpl extends AntStructuredElementImpl implements AntFilesProvider {
private AntPattern myPattern;
private volatile SoftReference<List<File>> myCachedFiles;
public AntFilesProviderImpl(final AntElement parent, final XmlTag sourceElement) {
super(parent, sourceElement);
}
public AntFilesProviderImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition, @NonNls final String nameElementAttribute) {
super(parent, sourceElement, definition, nameElementAttribute);
}
public AntFilesProviderImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition) {
super(parent, sourceElement, definition);
}
public void clearCaches() {
synchronized (PsiLock.LOCK) {
super.clearCaches();
myPattern = null;
clearCachedFiles();
final AntElement parent = getAntParent();
if (parent != null) {
parent.clearCaches();
}
}
}
public void clearCachedFiles() {
synchronized (PsiLock.LOCK) {
myCachedFiles = null;
}
}
@NotNull
public final List<File> getFiles(final Set<AntFilesProvider> processed) {
if (processed.contains(this)) {
return Collections.emptyList();
}
List<File> result = myCachedFiles == null? null : myCachedFiles.get();
if (result == null) {
result = getFilesImpl(processed);
myCachedFiles = new SoftReference<List<File>>(result);
}
return result;
}
private List<File> getFilesImpl(final Set<AntFilesProvider> processed) {
processed.add(this);
try {
final AntFilesProvider referenced = getReferencedProvider();
if (referenced != null) {
return referenced.getFiles(processed);
}
return getFiles(getPattern(), processed);
}
finally {
processed.remove(this);
}
}
@NotNull
protected List<File> getFiles(AntPattern pattern, final Set<AntFilesProvider> processed) {
return Collections.emptyList();
}
protected AntPattern getPattern() {
synchronized (PsiLock.LOCK) {
if (myPattern == null) {
myPattern = AntPattern.create(this, shouldHonorDefaultExcludes(), matchPatternsCaseSensitive());
}
return myPattern;
}
}
@Nullable
private AntFilesProvider getReferencedProvider() {
final PsiReference[] references = getReferences();
for (PsiReference reference : references) {
if (reference instanceof AntRefIdReference) {
final PsiElement psiElement = reference.resolve();
if (psiElement instanceof AntFilesProvider) {
return (AntFilesProvider)psiElement;
}
}
}
return null;
}
private boolean shouldHonorDefaultExcludes() {
@NonNls final String value = getSourceElement().getAttributeValue("defaultexcludes");
return value == null || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("true");
}
private boolean matchPatternsCaseSensitive() {
@NonNls final String value = getSourceElement().getAttributeValue("casesensitive");
return value == null || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("true");
}
@Nullable
protected File getCanonicalFile(final String path) {
if (path == null) {
return null;
}
try {
final File file = new File(path);
if (file.isAbsolute()) {
return file.getCanonicalFile();
}
final String baseDir = computeAttributeValue("${" + AntFileImpl.BASEDIR_ATTR + "}");
if (baseDir == null) {
return null;
}
return new File(baseDir, path).getCanonicalFile();
}
catch (IOException e) {
return null;
}
}
}
@@ -1,97 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.AntSupport;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntElementVisitor;
import com.intellij.lang.ant.psi.AntFile;
import com.intellij.lang.ant.psi.AntImport;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiLock;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.StringBuilderSpinAllocator;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
public class AntImportImpl extends AntTaskImpl implements AntImport {
public AntImportImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition) {
super(parent, sourceElement, definition);
}
public void acceptAntElementVisitor(@NotNull final AntElementVisitor visitor) {
visitor.visitAntImport(this);
}
public String toString() {
@NonNls final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append("AntImport[");
builder.append(getSourceElement().getAttributeValue(AntFileImpl.FILE_ATTR));
builder.append("]");
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
@NotNull
public List<String> getFileReferenceAttributes() {
return Collections.singletonList(AntFileImpl.FILE_ATTR);
}
@Nullable
public String getFileName() {
return computeAttributeValue(getSourceElement().getAttributeValue(AntFileImpl.FILE_ATTR));
}
public AntFile getImportedFile() {
return getImportedFile(getFileName(), this);
}
public void clearCaches() {
synchronized (PsiLock.LOCK) {
super.clearCaches();
getAntFile().clearCaches();
}
}
@Nullable
static AntFile getImportedFile(final String name, final AntStructuredElementImpl element) {
if (name == null) return null;
final PsiFile psiFile = element.findFileByName(name);
if (psiFile != null) {
if (psiFile instanceof XmlFile) {
final VirtualFile file = psiFile.getVirtualFile();
if (file != null) {
//AntSupport.markFileAsAntFile(file, psiFile.getViewProvider(), true);
}
return AntSupport.getAntFile(psiFile);
}
if (psiFile instanceof AntFile) return (AntFile)psiFile;
}
return null;
}
}
@@ -1,175 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.AntElementRole;
import com.intellij.lang.ant.psi.*;
import com.intellij.lang.ant.psi.introspection.AntAttributeType;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.lang.ant.psi.introspection.AntTypeId;
import com.intellij.lang.ant.psi.introspection.impl.AntTypeDefinitionImpl;
import com.intellij.psi.PsiLock;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.StringBuilderSpinAllocator;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
public class AntMacroDefImpl extends AntTaskImpl implements AntMacroDef {
@NonNls public static final String ANT_MACRODEF_NAME = "AntMacroDef";
private AntTypeDefinitionImpl myMacroDefinition;
public AntMacroDefImpl(final AntStructuredElement parent, final XmlTag sourceElement, final AntTypeDefinition definition) {
super(parent, sourceElement, definition);
invalidateMacroDefinition();
}
public void acceptAntElementVisitor(@NotNull final AntElementVisitor visitor) {
visitor.visitAntMacroDef(this);
}
public String toString() {
return createMacroClassName(getName());
}
public static String createMacroClassName(final String macroName) {
@NonNls final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append(ANT_MACRODEF_NAME);
builder.append("[");
builder.append(macroName);
builder.append("]");
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
public AntElementRole getRole() {
return AntElementRole.MACRODEF_ROLE;
}
public AntTypeDefinition getMacroDefinition() {
return myMacroDefinition;
}
public void clearCaches() {
synchronized (PsiLock.LOCK) {
super.clearCaches();
clearClassesCache();
getAntFile().clearCaches();
}
}
public void clearClassesCache() {
synchronized (PsiLock.LOCK) {
if (myMacroDefinition != null) {
final AntFile file = getAntFile();
for (AntTypeId id : myMacroDefinition.getNestedElements()) {
final AntTypeDefinition nestedDef = file.getBaseTypeDefinition(myMacroDefinition.getNestedClassName(id));
if (nestedDef != null) {
file.unregisterCustomType(nestedDef);
}
}
final AntStructuredElement parent = getAntProject();
if (parent != null) {
parent.unregisterCustomType(myMacroDefinition);
}
myMacroDefinition = null;
}
}
}
@SuppressWarnings({"HardCodedStringLiteral"})
private void invalidateMacroDefinition() {
if (!hasNameElement()) {
myMacroDefinition = null;
return;
}
final AntFile file = getAntFile();
if (file == null) return;
final String thisClassName = createMacroClassName(getName());
myMacroDefinition = (AntTypeDefinitionImpl)file.getBaseTypeDefinition(thisClassName);
final Map<String, AntAttributeType> attributes =
(myMacroDefinition == null) ? new HashMap<String, AntAttributeType>() : myMacroDefinition.getAttributesMap();
attributes.clear();
final Map<AntTypeId, String> nestedElements =
(myMacroDefinition == null) ? new HashMap<AntTypeId, String>() : myMacroDefinition.getNestedElementsMap();
for (AntElement child : getChildren()) {
if (child instanceof AntStructuredElement) {
final AntStructuredElement se = (AntStructuredElement)child;
final String name = se.getName();
if (name != null) {
final String tagName = se.getSourceElement().getName();
if (tagName.equals("attribute")) {
attributes.put(name.toLowerCase(Locale.US), AntAttributeType.STRING);
}
else if (tagName.equals("element")) {
final String elementClassName = thisClassName + '$' + name;
AntTypeDefinitionImpl nestedDef = (AntTypeDefinitionImpl)file.getBaseTypeDefinition(elementClassName);
if (nestedDef == null) {
final AntTypeDefinitionImpl targetDef = (AntTypeDefinitionImpl)file.getTargetDefinition();
if (targetDef != null) {
nestedDef = new AntTypeDefinitionImpl(targetDef);
}
}
if (nestedDef != null) {
final AntTypeId typeId = new AntTypeId(name);
nestedDef.setTypeId(typeId);
nestedDef.setClassName(elementClassName);
nestedDef.setIsTask(false);
nestedDef.setDefiningElement(child);
file.registerCustomType(nestedDef);
nestedElements.put(typeId, nestedDef.getClassName());
}
}
}
}
}
final AntTypeId definedTypeId = new AntTypeId(getName());
if (myMacroDefinition == null) {
myMacroDefinition = new AntTypeDefinitionImpl(definedTypeId, thisClassName, true, false, attributes, nestedElements, this);
}
else {
myMacroDefinition.setTypeId(definedTypeId);
myMacroDefinition.setClassName(thisClassName);
myMacroDefinition.setIsTask(true);
myMacroDefinition.setDefiningElement(this);
}
final AntStructuredElement parent = getAntProject();
if (parent != null) {
parent.registerCustomType(myMacroDefinition);
}
// define itself as nested task for sequential
final AntAllTasksContainerImpl sequential = PsiTreeUtil.getChildOfType(this, AntAllTasksContainerImpl.class);
if (sequential != null) {
sequential.registerCustomType(myMacroDefinition);
for (final AntTypeId id : myMacroDefinition.getNestedElements()) {
sequential.registerCustomType(file.getBaseTypeDefinition(myMacroDefinition.getNestedClassName(id)));
}
}
}
}
@@ -1,81 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntNameIdentifier;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
public class AntNameIdentifierImpl extends AntElementImpl implements AntNameIdentifier {
private String myCachedName;
private volatile long myModCount;
public AntNameIdentifierImpl(final AntElement parent, final XmlAttributeValue sourceElement) {
super(parent, sourceElement);
}
@NotNull
public XmlAttributeValue getSourceElement() {
return (XmlAttributeValue)super.getSourceElement();
}
public TextRange getTextRange() {
return getSourceElement().getValueTextRange();
}
public String getText() {
return getName();
}
public int getTextOffset() {
return getTextRange().getStartOffset();
}
public int getTextLength() {
return getText().length();
}
public String getName() {
return getIdentifierName();
}
public String getIdentifierName() {
String name = myCachedName;
final PsiManager psiManager = getManager();
final long modificationCount = psiManager != null? psiManager.getModificationTracker().getModificationCount() : myModCount;
if (name != null && myModCount == modificationCount) {
return name;
}
myModCount = modificationCount;
name = getSourceElement().getValue();
myCachedName = name;
return name;
}
public void setIdentifierName(@NotNull String name) throws IncorrectOperationException {
final XmlAttribute attr = PsiTreeUtil.getParentOfType(getSourceElement(), XmlAttribute.class, true);
if (attr != null) {
attr.setValue(name);
}
}
}
@@ -1,78 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.psi.AntFile;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiManager;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
/**
* element for wrapping xml out of the project tag, that can be xml prolog or smth
*/
public class AntOuterProjectElement extends AntElementImpl {
private final int myStartOffset;
private final String myText;
public AntOuterProjectElement(final AntFile parent, final int startOffset, final String text) {
super(parent, null);
myStartOffset = startOffset;
myText = text;
}
@NonNls
public String toString() {
return "XmlText: " + myText;
}
public boolean isPhysical() {
return getParent().isPhysical();
}
public boolean isValid() {
return getParent().isValid();
}
public PsiManager getManager() {
return getParent().getManager();
}
public TextRange getTextRange() {
return new TextRange(myStartOffset, myStartOffset + myText.length());
}
public int getTextLength() {
return myText.length();
}
public int getTextOffset() {
return myStartOffset;
}
public String getText() {
return myText;
}
@NotNull
public char[] textToCharArray() {
return myText.toCharArray();
}
public boolean textContains(char c) {
return myText.indexOf(c, 0) >= 0;
}
}
@@ -1,88 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntFilesProvider;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.psi.xml.XmlTag;
import org.apache.tools.ant.PathTokenizer;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* @author Eugene Zhuravlev
* Date: May 5, 2007
*/
public class AntPathImpl extends AntFilesProviderImpl{
public AntPathImpl(final AntElement parent, final XmlTag sourceElement) {
super(parent, sourceElement);
}
public AntPathImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition, @NonNls final String nameElementAttribute) {
super(parent, sourceElement, definition, nameElementAttribute);
}
public AntPathImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition) {
super(parent, sourceElement, definition);
}
protected AntPattern getPattern() {
return null; // not available
}
@NotNull
protected List<File> getFiles(final AntPattern pattern, final Set<AntFilesProvider> processed) {
final List<File> files = new ArrayList<File>();
final File baseDir = getCanonicalFile(".");
addLocation(baseDir, files, computeAttributeValue(getSourceElement().getAttributeValue("location")));
final String pathString = computeAttributeValue(getSourceElement().getAttributeValue("path"));
if (pathString != null) {
final PathTokenizer tokenizer = new PathTokenizer(pathString);
while (tokenizer.hasMoreTokens()) {
addLocation(baseDir, files, tokenizer.nextToken());
}
}
final AntElement[] children = getChildren();
for (AntElement child : children) {
if (child instanceof AntFilesProvider) {
files.addAll(((AntFilesProvider)child).getFiles(processed));
}
}
return files;
}
private static void addLocation(final File baseDir, final List<File> files, final String locationPath) {
if (locationPath != null) {
File file = new File(locationPath);
if (file.isAbsolute()) {
files.add(file);
}
else {
files.add(new File(baseDir, locationPath));
}
}
}
}
@@ -1,276 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.psi.AntElementVisitor;
import com.intellij.lang.ant.psi.AntFile;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.lang.ant.psi.impl.reference.AntRefIdReference;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.lang.ant.psi.introspection.AntTypeId;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.xml.XmlTag;
import org.jetbrains.annotations.NonNls;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
/**
* @author Eugene Zhuravlev
* Date: May 2, 2007
*/
public class AntPattern extends AntElementVisitor {
private static final List<Pattern> ourDefaultExcludes = new ArrayList<Pattern>(getDefaultExcludes(true));
private static final List<Pattern> ourCaseInsensitiveDefaultExcludes = new ArrayList<Pattern>(getDefaultExcludes(false));
private final boolean myCaseSensitive;
private static final String ourSeparatorPattern = Pattern.quote("/");
private static List<Pattern> getDefaultExcludes(final boolean caseSensitive) {
return Arrays.asList(
convertToRegexPattern("**/*~", caseSensitive),
convertToRegexPattern("**/#*#", caseSensitive),
convertToRegexPattern("**/.#*", caseSensitive),
convertToRegexPattern("**/%*%", caseSensitive),
convertToRegexPattern("**/._*", caseSensitive),
convertToRegexPattern("**/CVS", caseSensitive),
convertToRegexPattern("**/CVS/**", caseSensitive),
convertToRegexPattern("**/.cvsignore", caseSensitive),
convertToRegexPattern("**/SCCS", caseSensitive),
convertToRegexPattern("**/SCCS/**", caseSensitive),
convertToRegexPattern("**/vssver.scc", caseSensitive),
convertToRegexPattern("**/.svn", caseSensitive),
convertToRegexPattern("**/.svn/**", caseSensitive),
convertToRegexPattern("**/_svn", caseSensitive),
convertToRegexPattern("**/_svn/**", caseSensitive),
convertToRegexPattern("**/.DS_Store", caseSensitive)
);
}
private final List<Pattern> myIncludePatterns = new ArrayList<Pattern>();
private final List<Pattern> myExcludePatterns = new ArrayList<Pattern>();
private final List<PrefixItem[]> myCouldBeIncludedPatterns = new ArrayList<PrefixItem[]>();
AntPattern(final boolean caseSensitive) {
myCaseSensitive = caseSensitive;
}
public boolean hasIncludePatterns() {
return myIncludePatterns.size() > 0;
}
@Override public void visitAntStructuredElement(final AntStructuredElement element) {
final AntTypeDefinition typeDef = element.getTypeDefinition();
if (typeDef != null) {
final AntTypeId antTypeId = typeDef.getTypeId();
// todo: add support to includefile and excludefile
if ("include".equals(antTypeId.getName())) {
if (isEnabled(element)) {
final String value = element.computeAttributeValue(element.getSourceElement().getAttributeValue("name"));
if (value != null) {
addIncludePattern(value);
}
}
}
else if ("exclude".equals(antTypeId.getName())) {
if (isEnabled(element)) {
final String value = element.computeAttributeValue(element.getSourceElement().getAttributeValue("name"));
if (value != null) {
addExcludePattern(value);
}
}
}
else {
// todo: add support to includesfile and excludesfile
final String includeAttribs = element.computeAttributeValue(element.getSourceElement().getAttributeValue("includes"));
if (includeAttribs != null) {
addPatterns(true, includeAttribs);
}
final String excludeAttribs = element.computeAttributeValue(element.getSourceElement().getAttributeValue("excludes"));
if (excludeAttribs != null) {
addPatterns(false, excludeAttribs);
}
}
final PsiReference[] refs = element.getReferences();
for (PsiReference ref : refs) {
if (ref instanceof AntRefIdReference) {
final PsiElement psiElement = ref.resolve();
if (psiElement instanceof AntStructuredElement) {
((AntStructuredElement)psiElement).acceptAntElementVisitor(this);
}
}
}
}
super.visitAntStructuredElement(element);
}
public final void addExcludePattern(final String antPattern) {
myExcludePatterns.add(convertToRegexPattern(antPattern, myCaseSensitive));
}
public final void addIncludePattern(final String antPattern) {
myIncludePatterns.add(convertToRegexPattern(antPattern, myCaseSensitive));
String normalizedPattern = antPattern.endsWith("/") || antPattern.endsWith(File.separator)? antPattern.replace(File.separatorChar, '/') + "**" : antPattern.replace(File.separatorChar, '/');
if (normalizedPattern.startsWith("/") && normalizedPattern.length() > 1) {
// cut first leading slash if any
normalizedPattern = normalizedPattern.substring(1, normalizedPattern.length());
}
if (!normalizedPattern.startsWith("/")) {
final String[] patDirs = normalizedPattern.split(ourSeparatorPattern);
final PrefixItem[] items = new PrefixItem[patDirs.length];
for (int i = 0; i < patDirs.length; i++) {
items[i] = new PrefixItem(patDirs[i]);
}
myCouldBeIncludedPatterns.add(items);
}
}
public boolean acceptPath(final String relativePath) {
final String path = relativePath.replace('\\', '/');
boolean accepted = myIncludePatterns.size() == 0;
for (Pattern includePattern : myIncludePatterns) {
if (includePattern.matcher(path).matches()) {
accepted = true;
break;
}
}
if (accepted) {
for (Pattern excludePattern : myExcludePatterns) {
if (excludePattern.matcher(path).matches()) {
accepted = false;
break;
}
}
}
return accepted;
}
private static boolean isEnabled(AntStructuredElement element) {
final XmlTag srcElem = element.getSourceElement();
final AntFile antFile = element.getAntFile();
final String ifProperty = srcElem.getAttributeValue("if");
if (ifProperty != null && antFile.getProperty(ifProperty) == null) {
return false;
}
final String unlessProperty = srcElem.getAttributeValue("unless");
if (unlessProperty != null && antFile.getProperty(unlessProperty) != null) {
return false;
}
return true;
}
private void addPatterns(final boolean addToIncludes, final String patternString) {
final StringTokenizer tokenizer = new StringTokenizer(patternString, ", \t", false);
while (tokenizer.hasMoreTokens()) {
final String pattern = tokenizer.nextToken();
if (pattern.length() > 0) {
if (addToIncludes) {
addIncludePattern(pattern);
}
else {
addExcludePattern(pattern);
}
}
}
}
private static Pattern convertToRegexPattern(@NonNls final String antPattern, final boolean caseSensitive) {
return Pattern.compile(FileUtil.convertAntToRegexp(antPattern), caseSensitive? 0 : Pattern.CASE_INSENSITIVE);
}
public static AntPattern create(AntStructuredElement element, final boolean honorDefaultExcludes, final boolean caseSensitive) {
final AntPattern antPattern = new AntPattern(caseSensitive);
element.acceptAntElementVisitor(antPattern);
if (honorDefaultExcludes) {
antPattern.myExcludePatterns.addAll(caseSensitive? ourDefaultExcludes : ourCaseInsensitiveDefaultExcludes);
}
return antPattern;
}
// from org.apache.tools.ant.DirectoryScanner
protected static boolean matchPatternStart(PrefixItem[] patDirs, String str) {
final String[] strDirs = str.split(ourSeparatorPattern);
int patIdxStart = 0;
final int patIdxEnd = patDirs.length-1;
int strIdxStart = 0;
final int strIdxEnd = strDirs.length-1;
// up to first '**'
while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
final AntPattern.PrefixItem item = patDirs[patIdxStart];
if ("**".equals(item.getStrPattern())) {
break;
}
if (!item.getPattern().matcher(strDirs[strIdxStart]).matches()) {
return false;
}
patIdxStart++;
strIdxStart++;
}
if (strIdxStart > strIdxEnd) {
// String is exhausted
return true;
}
if (patIdxStart > patIdxEnd) {
// String not exhausted, but pattern is. Failure.
return false;
}
// pattern now holds ** while string is not exhausted
// this will generate false positives but we can live with that.
return true;
}
public boolean couldBeIncluded(String relativePath) {
if (myIncludePatterns.size() == 0) {
return true;
}
for (PrefixItem[] couldBeIncludedPattern : myCouldBeIncludedPatterns) {
if (matchPatternStart(couldBeIncludedPattern, relativePath)) {
return true;
}
}
return false;
}
private class PrefixItem {
private final String myStrPattern;
private Pattern myCompiledPattern;
public PrefixItem(String strPattern) {
myStrPattern = strPattern;
}
public String getStrPattern() {
return myStrPattern;
}
public Pattern getPattern() {
if (myCompiledPattern == null) {
myCompiledPattern = Pattern.compile(FileUtil.convertAntToRegexp(myStrPattern), myCaseSensitive ? 0 : Pattern.CASE_INSENSITIVE);
}
return myCompiledPattern;
}
}
}
@@ -1,114 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.psi.AntElementVisitor;
import com.intellij.lang.ant.psi.AntPresetDef;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.lang.ant.psi.introspection.AntAttributeType;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.lang.ant.psi.introspection.AntTypeId;
import com.intellij.lang.ant.psi.introspection.impl.AntTypeDefinitionImpl;
import com.intellij.psi.PsiLock;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.StringBuilderSpinAllocator;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
public class AntPresetDefImpl extends AntAllTasksContainerImpl implements AntPresetDef {
@NonNls public static final String ANT_PRESETDEF_NAME = "AntPresetDef";
private AntTypeDefinitionImpl myPresetDefinition;
public AntPresetDefImpl(final AntStructuredElement parent, final XmlTag sourceElement, final AntTypeDefinition definition) {
super(parent, sourceElement, definition);
invalidatePresetDefinition();
}
public String toString() {
return createPresetDefClassName(getName());
}
public void acceptAntElementVisitor(@NotNull final AntElementVisitor visitor) {
visitor.visitAntPresetDef(this);
}
public static String createPresetDefClassName(final String presetDefName) {
@NonNls final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append(ANT_PRESETDEF_NAME);
builder.append("[");
builder.append(presetDefName);
builder.append("]");
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
public AntTypeDefinition getPresetDefinition() {
return myPresetDefinition;
}
public void clearCaches() {
synchronized (PsiLock.LOCK) {
super.clearCaches();
clearClassesCache();
getAntFile().clearCaches();
}
}
public void clearClassesCache() {
synchronized (PsiLock.LOCK) {
if (myPresetDefinition != null) {
final AntStructuredElement parent = getAntProject();
if (parent != null) {
parent.unregisterCustomType(myPresetDefinition);
}
myPresetDefinition = null;
}
}
}
@SuppressWarnings({"HardCodedStringLiteral"})
private void invalidatePresetDefinition() {
myPresetDefinition = null;
if (!hasNameElement()) return;
final String thisClassName = createPresetDefClassName(getName());
final AntStructuredElementImpl extented = PsiTreeUtil.getChildOfType(this, AntStructuredElementImpl.class);
final AntTypeId typeId = new AntTypeId(getName());
if (extented != null) {
final AntTypeDefinitionImpl extentedDef = (AntTypeDefinitionImpl)extented.getTypeDefinition();
if (extentedDef != null) {
myPresetDefinition = new AntTypeDefinitionImpl(typeId, thisClassName, extentedDef.isTask(), false, extentedDef.getAttributesMap(),
extentedDef.getNestedElementsMap(), this);
}
}
if (myPresetDefinition == null) {
myPresetDefinition = new AntTypeDefinitionImpl(typeId, thisClassName, false, false, new HashMap<String, AntAttributeType>(),
new HashMap<AntTypeId, String>(), this);
}
final AntStructuredElement parent = getAntProject();
if (parent != null) {
parent.registerCustomType(myPresetDefinition);
}
}
}
@@ -1,334 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.AntElementRole;
import com.intellij.lang.ant.misc.PsiElementSetSpinAllocator;
import com.intellij.lang.ant.psi.*;
import com.intellij.lang.ant.psi.impl.reference.AntTargetReference;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.LocalTimeCounter;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@SuppressWarnings({"HardCodedStringLiteral"})
public class AntProjectImpl extends AntStructuredElementImpl implements AntProject {
private volatile AntTarget[] myTargets;
private volatile AntTarget[] myImportedTargets;
private volatile List<AntFile> myImports;
private AntFile[] myCachedImportsArray;
private volatile Map<String, AntElement> myReferencedElements;
private volatile String[] myRefIdsArray;
public AntProjectImpl(final AntFileImpl parent, final XmlTag tag, final AntTypeDefinition projectDefinition) {
super(parent, tag);
myDefinition = projectDefinition;
}
public void acceptAntElementVisitor(@NotNull final AntElementVisitor visitor) {
visitor.visitAntProject(this);
}
@NonNls
public String toString() {
final @NonNls StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append("AntProject[");
final String name = getName();
builder.append((name == null) ? "unnamed" : name);
builder.append("]");
if (getDescription() != null) {
builder.append(" :");
builder.append(getDescription());
}
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
public AntElementRole getRole() {
return AntElementRole.PROJECT_ROLE;
}
public void clearCaches() {
synchronized (PsiLock.LOCK) {
super.clearCaches();
myTargets = null;
clearImports();
myReferencedElements = null;
myRefIdsArray = null;
final AntFile antFile = getAntFile();
if (antFile != null) {
antFile.invalidateProperties();
}
}
}
public void clearImports() {
synchronized (PsiLock.LOCK) {
if (myBuildingImports == 0) {
myImports = null;
}
myCachedImportsArray = null;
myImportedTargets = null;
}
}
@Nullable
public String getBaseDir() {
return computeAttributeValue(getSourceElement().getAttributeValue(AntFileImpl.BASEDIR_ATTR));
}
@Nullable
public String getDescription() {
final XmlTag tag = getSourceElement().findFirstSubTag(AntFileImpl.DESCRIPTION_ATTR);
return tag != null ? tag.getValue().getTrimmedText() : null;
}
@NotNull
public AntTarget[] getTargets() {
synchronized (PsiLock.LOCK) {
if (myTargets != null) {
return myTargets;
}
//noinspection NonPrivateFieldAccessedInSynchronizedContext
if (myInGettingChildren) {
return AntTarget.EMPTY_ARRAY;
}
final List<AntTarget> targets = new ArrayList<AntTarget>();
for (final AntElement child : getChildren()) {
if (child instanceof AntTarget) {
targets.add((AntTarget)child);
}
}
final int size = targets.size();
return myTargets = (size == 0) ? AntTarget.EMPTY_ARRAY : targets.toArray(new AntTarget[size]);
}
}
@Nullable
public AntTarget getDefaultTarget() {
for (final PsiReference ref : getReferences()) {
if (ref instanceof AntTargetReference) {
return (AntTarget)ref.resolve();
}
}
return null;
}
@NotNull
public AntTarget[] getImportedTargets() {
synchronized (PsiLock.LOCK) {
if (myImportedTargets == null) {
if (getImportedFiles().length == 0) {
myImportedTargets = AntTarget.EMPTY_ARRAY;
}
else {
final Set<PsiElement> targets = PsiElementSetSpinAllocator.alloc();
try {
final Set<PsiElement> elementsDepthStack = PsiElementSetSpinAllocator.alloc();
try {
getImportedTargets(this, targets, elementsDepthStack);
}
finally {
PsiElementSetSpinAllocator.dispose(elementsDepthStack);
}
final int size = targets.size();
myImportedTargets = (size == 0) ? AntTarget.EMPTY_ARRAY : targets.toArray(new AntTarget[size]);
}
finally {
PsiElementSetSpinAllocator.dispose(targets);
}
}
}
}
return myImportedTargets;
}
@Nullable
public AntTarget getTarget(final String name) {
for (final AntTarget target : getTargets()) {
if (name.equals(target.getName())) {
return target;
}
}
return null;
}
/**
* This method returns not only files that could be included via the <import>
* task, but also a fake file which aggregates definitions resolved from all
* entity references under the root tag.
*/
private int myBuildingImports = 0;
@NotNull
public AntFile[] getImportedFiles() {
synchronized (PsiLock.LOCK) {
if (myImports == null) {
// this is necessary to avoid recurrent getImportedFiles() and stack overflow
myImports = new ArrayList<AntFile>();
final XmlTag se = getSourceElement();
final PsiFile psiFile = se.getContainingFile();
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
myBuildingImports++;
try {
for (final XmlTag tag : se.getSubTags()) {
// !!! a tag doesn't belong to the current file, so we decide it's resolved via an entity ref
if (!psiFile.equals(tag.getContainingFile())) {
buildTagText(tag, builder);
}
else if (AntFileImpl.IMPORT_TAG.equals(tag.getName())) {
final String fileName = tag.getAttributeValue(AntFileImpl.FILE_ATTR);
if (fileName != null) {
final AntFile imported = AntImportImpl.getImportedFile(fileName, this);
if (imported != null) {
addImportedFile(imported);
}
}
}
}
if (builder.length() > 0) {
builder.insert(0, "\">");
final String baseDir = getBaseDir();
if (baseDir != null && baseDir.length() > 0) {
builder.insert(0, baseDir);
}
builder.insert(0, "<project basedir=\"");
builder.append("</project>");
final XmlFile xmlFile = (XmlFile)PsiFileFactory.getInstance(getProject())
.createFileFromText("dummyEntities.xml", StdFileTypes.XML, builder.toString(), LocalTimeCounter.currentTime(), false, false);
addImportedFile(new AntFileImpl(xmlFile.getViewProvider()) {
//
// this is necessary for computing file paths in tags resolved as entity references
//
public VirtualFile getContainingPath() {
return AntProjectImpl.this.getAntFile().getContainingPath();
}
});
}
}
finally {
StringBuilderSpinAllocator.dispose(builder);
myBuildingImports--;
myCachedImportsArray = null;
myImportedTargets = null;
}
}
if (myCachedImportsArray == null) {
myCachedImportsArray = myImports.toArray(new AntFile[myImports.size()]);
}
return myCachedImportsArray;
}
}
private void addImportedFile(final AntFile imported) {
try {
myImports.add(imported);
}
finally {
myCachedImportsArray = null;
}
}
public void registerRefId(final String id, AntElement element) {
synchronized (PsiLock.LOCK) {
if (id == null || id.length() == 0) return;
if (myReferencedElements == null) {
myReferencedElements = new HashMap<String, AntElement>();
}
myReferencedElements.put(id, element);
}
}
@Nullable
public AntElement getElementByRefId(String refid) {
synchronized (PsiLock.LOCK) {
if (myReferencedElements == null) return null;
refid = computeAttributeValue(refid);
return myReferencedElements.get(refid);
}
}
@NotNull
public String[] getRefIds() {
synchronized (PsiLock.LOCK) {
if (myRefIdsArray == null) {
if (myReferencedElements == null) {
myRefIdsArray = ArrayUtil.EMPTY_STRING_ARRAY;
}
else {
myRefIdsArray = myReferencedElements.keySet().toArray(new String[myReferencedElements.size()]);
}
}
return myRefIdsArray;
}
}
private static void getImportedTargets(final AntProject project,
final Set<PsiElement> targets,
final Set<PsiElement> elementsDepthStack) {
if (elementsDepthStack.contains(project)) return;
elementsDepthStack.add(project);
try {
for (final AntFile imported : project.getImportedFiles()) {
final AntProject importedProject = imported.getAntProject();
if (importedProject != null && !elementsDepthStack.contains(importedProject)) {
for (final AntTarget target : importedProject.getTargets()) {
targets.add(target);
}
}
getImportedTargets(importedProject, targets, elementsDepthStack);
}
}
finally {
elementsDepthStack.remove(project);
}
}
private static void buildTagText(final XmlTag tag, final StringBuilder builder) {
//
// this quite strange creation of the tag text is necessary since
// tag.getText() removes whitespaces from source text
//
boolean firstChild = true;
for (final PsiElement tagChild : tag.getChildren()) {
if (!firstChild) {
builder.append(' ');
}
if (tagChild instanceof XmlTag) {
buildTagText((XmlTag)tagChild, builder);
}
else {
builder.append(tagChild.getText());
}
firstChild = false;
}
}
}
@@ -1,434 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.AntElementRole;
import com.intellij.lang.ant.psi.*;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiLock;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.StringSetSpinAllocator;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
public class AntPropertyImpl extends AntTaskImpl implements AntProperty {
private PsiElement myPropertiesFile;
private static final Set<String> ourPropertyDefiningTags = new HashSet<String>(Arrays.asList(
AntFileImpl.PROPERTY,
"param",
"condition",
"input",
"available"
));
public AntPropertyImpl(final AntElement parent,
final XmlTag sourceElement,
final AntTypeDefinition definition,
@NonNls final String nameElementAttribute) {
super(parent, sourceElement, definition, nameElementAttribute);
}
public AntPropertyImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition) {
this(parent, sourceElement, definition, AntFileImpl.NAME_ATTR);
}
public PsiElement setName(@NotNull final String name) throws IncorrectOperationException {
final AntProperty element = (AntProperty)super.setName(name);
final AntFile antFile = getAntFile();
antFile.invalidateProperties();
return element;
}
public void acceptAntElementVisitor(@NotNull final AntElementVisitor visitor) {
visitor.visitAntProperty(this);
}
public String toString() {
final @NonNls StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append("AntProperty[");
if (getName() != null) {
builder.append(getName());
builder.append(" = ");
builder.append(getValue(null));
}
else {
final String propFile = getFileName();
if (propFile != null) {
builder.append("file: ");
builder.append(propFile);
}
else {
builder.append(getSourceElement().getName());
}
}
builder.append("]");
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
public String getName() {
final XmlAttributeValue[] values = getTstampPropertyAttributeValues();
return (values.length == 1) ? values[0].getValue() : super.getName();
}
public AntElementRole getRole() {
return AntElementRole.PROPERTY_ROLE;
}
public boolean canRename() {
return super.canRename() && (!isTstamp() || getTstampPropertyAttributeValues().length > 0);
}
@SuppressWarnings({"HardCodedStringLiteral"})
@Nullable
public String getValue(final String propName) {
synchronized (PsiLock.LOCK) {
final XmlTag se = getSourceElement();
final String tagName = se.getName();
if (ourPropertyDefiningTags.contains(tagName)) { // todo: support conditions separately
String value = getPropertyValue();
if (value == null && propName != null) {
final PropertiesFile propertiesFile = getPropertiesFile();
if (propertiesFile != null) {
final IProperty fileProperty = propertiesFile.findPropertyByKey(cutPrefix(propName));
if (fileProperty != null) {
value = fileProperty.getValue();
}
}
}
return value;
}
else if ("dirname".equals(tagName)) {
return getDirnameValue();
}
else if (isTstamp()) {
return getTstampValue(propName);
}
return null;
}
}
private String cutPrefix(@NotNull final String propName) {
final String prefix = getPrefix();
if (prefix != null && propName.startsWith(prefix) && prefix.length() < propName.length() && propName.charAt(prefix.length()) == '.') {
return propName.substring(prefix.length() + 1);
}
return propName;
}
@Nullable
public String getFileName() {
return computeAttributeValue(getSourceElement().getAttributeValue(AntFileImpl.FILE_ATTR));
}
@Nullable
public PropertiesFile getPropertiesFile() {
synchronized (PsiLock.LOCK) {
if (myPropertiesFile == null) {
myPropertiesFile = AntElementImpl.ourNull;
final String name = getFileName();
if (name != null) {
final PsiFile psiFile = findFileByName(name, null);
if (psiFile instanceof PropertiesFile) {
myPropertiesFile = psiFile;
}
}
}
return (myPropertiesFile == AntElementImpl.ourNull) ? null : (PropertiesFile)myPropertiesFile;
}
}
@Nullable
public String getPrefix() {
return computeAttributeValue(getSourceElement().getAttributeValue(AntFileImpl.PREFIX_ATTR));
}
@Nullable
public String getEnvironment() {
return computeAttributeValue(getSourceElement().getAttributeValue("environment"));
}
@Nullable
public String[] getNames() {
if (isTstamp()) {
return getTstampNames();
}
final PropertiesFile propertiesFile = getPropertiesFile();
if (propertiesFile != null) {
final List<IProperty> propList = propertiesFile.getProperties();
final String prefix = getPrefix();
final String[] names = ArrayUtil.newStringArray(propList.size());
int idx = 0;
for (final IProperty importedProp : propList) {
names[idx++] = prefix != null? prefix + "." + importedProp.getName() : importedProp.getName();
}
return names;
}
final String name = getName();
if (name != null) {
if (getAntFile().isEnvironmentProperty(name)) {
return getEnvironmentNames(name);
}
return new String[]{name};
}
return null;
}
public void clearCaches() {
synchronized (PsiLock.LOCK) {
super.clearCaches();
final AntFile antFile = getAntFile();
if (antFile != null) {
antFile.clearCaches();
}
myPropertiesFile = null;
}
}
public int getTextOffset() {
final XmlAttributeValue[] values = getTstampPropertyAttributeValues();
return (values.length == 1) ? values[0].getTextOffset() : super.getTextOffset();
}
/**
* @return <format> element for the <tstamp> property
* @param propName
*/
@Nullable
@SuppressWarnings({"HardCodedStringLiteral"})
public AntElement getFormatElement(final String propName) {
for (final AntElement child : getChildren()) {
if (child instanceof AntStructuredElement) {
final AntStructuredElement se = (AntStructuredElement)child;
final XmlTag tag = se.getSourceElement();
if (AntFileImpl.FORMAT_TAG.equals(tag.getName())) {
if (propName.equals(tag.getAttributeValue(AntFileImpl.PROPERTY))) {
return child;
}
}
}
}
return this;
}
@Nullable
private String getPropertyValue() {
final XmlTag sourceElement = getSourceElement();
final String tagName = sourceElement.getName();
if ("available".equals(tagName)) {
// check only 'file' tag because others could be examined only at runtime
final String filePath = sourceElement.getAttributeValue("file");
if (filePath != null) {
final String _filePath = computeAttributeValue(filePath);
if (_filePath != null) {
if (!new File(_filePath).exists()) {
return null;
}
}
}
}
String value = sourceElement.getAttributeValue("value");
if (value == null) {
value = sourceElement.getAttributeValue("location");
if (value == null) {
value = sourceElement.getAttributeValue("defaultvalue");
}
}
return value;/*computeAttributeValue(value);*/
}
@Nullable
private String getDirnameValue() {
final XmlTag sourceElement = getSourceElement();
final String value = computeAttributeValue(sourceElement.getAttributeValue(AntFileImpl.FILE_ATTR));
if (value != null) {
return new File(value).getParent();
}
return value;
}
@SuppressWarnings({"HardCodedStringLiteral"})
private String getTstampValue(final String propName) {
final XmlTag se = getSourceElement();
Date d = new Date();
final XmlTag formatTag = se.findFirstSubTag(AntFileImpl.FORMAT_TAG);
if (formatTag != null) {
final String offsetStr = formatTag.getAttributeValue("offset");
int offset;
if (offsetStr != null) {
try {
offset = Integer.parseInt(offsetStr);
}
catch (NumberFormatException e) {
offset = 0;
}
final String unitStr = formatTag.getAttributeValue("unit");
int unit = 0;
if (unitStr != null) {
if ("millisecond".equals(unitStr)) {
unit = Calendar.MILLISECOND;
}
else if ("second".equals(unitStr)) {
unit = Calendar.SECOND;
}
else if ("minute".equals(unitStr)) {
unit = Calendar.MINUTE;
}
else if ("hour".equals(unitStr)) {
unit = Calendar.HOUR_OF_DAY;
}
else if ("day".equals(unitStr)) {
unit = Calendar.DAY_OF_MONTH;
}
else if ("week".equals(unitStr)) {
unit = Calendar.WEEK_OF_YEAR;
}
else if ("year".equals(unitStr)) {
unit = Calendar.YEAR;
}
}
if (offset != 0 && unit != 0) {
final Calendar cal = Calendar.getInstance();
cal.setTime(d);
cal.add(unit, offset);
d = cal.getTime();
}
}
}
final String _propName = propName != null? cutPrefix(propName) : null;
if (_propName != null) {
if (_propName.equals("DSTAMP")) {
return new SimpleDateFormat("yyyyMMdd").format(d);
}
else if (_propName.equals("TSTAMP")) {
return new SimpleDateFormat("HHmm").format(d);
}
else if (_propName.equals("TODAY")) {
return new SimpleDateFormat("MMMM d yyyy", Locale.US).format(d);
}
}
for (XmlAttributeValue value : getTstampPropertyAttributeValues()) {
if (value != null && (_propName == null || _propName.equals(value.getValue()))) {
if (formatTag != null) {
final String pattern = formatTag.getAttributeValue(TSTAMP_PATTERN_ATTRIBUTE_NAME);
try {
final DateFormat format = (pattern != null) ? new SimpleDateFormat(pattern) : DateFormat.getTimeInstance();
final String tz = formatTag.getAttributeValue(TSTAMP_TIMEZONE_ATTRIBUTE_NAME);
if (tz != null) {
format.setTimeZone(TimeZone.getTimeZone(tz));
}
return format.format(d);
}
catch (IllegalArgumentException ignored) {
return null;
}
}
}
}
return null;
}
private XmlAttributeValue[] getTstampPropertyAttributeValues() {
if (isTstamp()) {
final List<XmlAttributeValue> elements = new ArrayList<XmlAttributeValue>();
for (XmlTag formatTag : getSourceElement().findSubTags(AntFileImpl.FORMAT_TAG)) {
final XmlAttribute propAttr = formatTag.getAttribute(AntFileImpl.PROPERTY, null);
if (propAttr != null) {
final XmlAttributeValue value = propAttr.getValueElement();
if (value != null) {
elements.add(value);
}
}
}
return elements.toArray(new XmlAttributeValue[elements.size()]);
}
return new XmlAttributeValue[0];
}
public boolean isTstamp() {
return TSTAMP_TAG.equals(getSourceElement().getName());
}
private String[] getTstampNames() {
@NonNls final Set<String> strings = StringSetSpinAllocator.alloc();
try {
String prefix = getSourceElement().getAttributeValue(AntFileImpl.PREFIX_ATTR);
if (prefix == null) {
strings.add("DSTAMP");
strings.add("TSTAMP");
strings.add("TODAY");
}
else {
prefix += '.';
strings.add(prefix + "DSTAMP");
strings.add(prefix + "TSTAMP");
strings.add(prefix + "TODAY");
}
for (XmlAttributeValue value : getTstampPropertyAttributeValues()) {
if (value != null && value.getValue() != null) {
final String additionalProperty = value.getValue();
if (prefix == null) {
strings.add(additionalProperty);
}
else {
strings.add(prefix + additionalProperty);
}
}
}
return ArrayUtil.toStringArray(strings);
}
finally {
StringSetSpinAllocator.dispose(strings);
}
}
private String[] getEnvironmentNames(final String name) {
@NonNls final Set<String> strings = StringSetSpinAllocator.alloc();
try {
final String sourceName = name.substring(AntFileImpl.DEFAULT_ENVIRONMENT_PREFIX.length());
for (final String prefix : getAntFile().getEnvironmentPrefixes()) {
strings.add(prefix + sourceName);
}
return ArrayUtil.toStringArray(strings);
}
finally {
StringSetSpinAllocator.dispose(strings);
}
}
}
@@ -1,186 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.AntElementRole;
import com.intellij.lang.ant.psi.*;
import com.intellij.lang.ant.psi.introspection.AntAttributeType;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.lang.ant.psi.introspection.AntTypeId;
import com.intellij.lang.ant.psi.introspection.impl.AntTypeDefinitionImpl;
import com.intellij.psi.PsiLock;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.StringBuilderSpinAllocator;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
public class AntScriptDefImpl extends AntTaskImpl implements AntScriptDef {
@NonNls public static final String ANT_SCRIPTDEF_NAME = "AntScriptDef";
private AntTypeDefinitionImpl myScriptDefinition;
public AntScriptDefImpl(final AntStructuredElement parent, final XmlTag sourceElement, final AntTypeDefinition definition) {
super(parent, sourceElement, definition);
invalidateScriptDefinition();
}
public String toString() {
return createScriptClassName(getName());
}
public static String createScriptClassName(final String macroName) {
@NonNls final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append(ANT_SCRIPTDEF_NAME);
builder.append("[");
builder.append(macroName);
builder.append("]");
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
public AntElementRole getRole() {
return AntElementRole.SCRIPTDEF_ROLE;
}
public void acceptAntElementVisitor(@NotNull final AntElementVisitor visitor) {
visitor.visitAntScriptDef(this);
}
public AntTypeDefinition getScriptDefinition() {
return myScriptDefinition;
}
public void clearCaches() {
synchronized (PsiLock.LOCK) {
super.clearCaches();
final AntFile file = getAntFile();
clearClassesCache();
file.clearCaches();
}
}
public void clearClassesCache() {
synchronized (PsiLock.LOCK) {
if (myScriptDefinition != null) {
final AntFile file = getAntFile();
final AntAllTasksContainerImpl sequential = PsiTreeUtil.getChildOfType(this, AntAllTasksContainerImpl.class);
if (sequential != null) {
sequential.unregisterCustomType(myScriptDefinition);
}
for (AntTypeId id : myScriptDefinition.getNestedElements()) {
final AntTypeDefinition nestedDef = file.getBaseTypeDefinition(myScriptDefinition.getNestedClassName(id));
if (nestedDef != null) {
file.unregisterCustomType(nestedDef);
if (sequential != null) {
sequential.unregisterCustomType(nestedDef);
}
}
}
final AntStructuredElement parent = getAntProject();
if (parent != null) {
parent.unregisterCustomType(myScriptDefinition);
}
myScriptDefinition = null;
}
}
}
@SuppressWarnings({"HardCodedStringLiteral"})
private void invalidateScriptDefinition() {
if (!hasNameElement()) {
myScriptDefinition = null;
return;
}
final AntFile file = getAntFile();
if (file == null) return;
final String thisClassName = createScriptClassName(getName());
myScriptDefinition = (AntTypeDefinitionImpl)file.getBaseTypeDefinition(thisClassName);
final Map<String, AntAttributeType> attributes =
(myScriptDefinition == null) ? new HashMap<String, AntAttributeType>() : myScriptDefinition.getAttributesMap();
attributes.clear();
final Map<AntTypeId, String> nestedElements =
(myScriptDefinition == null) ? new HashMap<AntTypeId, String>() : myScriptDefinition.getNestedElementsMap();
for (AntElement child : getChildren()) {
if (child instanceof AntStructuredElement) {
final AntStructuredElement se = (AntStructuredElement)child;
final String name = se.getName();
if (name != null) {
final XmlTag sourceElement = se.getSourceElement();
final String tagName = sourceElement.getName();
if (tagName.equals("attribute")) {
attributes.put(name.toLowerCase(Locale.US), AntAttributeType.STRING);
}
else if (tagName.equals("element")) {
final String classNameAttrib = sourceElement.getAttributeValue("classname");
final String elementClassName = classNameAttrib != null? classNameAttrib : thisClassName + '$' + name;
AntTypeDefinitionImpl nestedDef = (AntTypeDefinitionImpl)file.getBaseTypeDefinition(elementClassName);
if (nestedDef == null) {
final AntTypeDefinitionImpl targetDef = (AntTypeDefinitionImpl)file.getTargetDefinition();
if (targetDef != null) {
nestedDef = new AntTypeDefinitionImpl(targetDef);
}
}
if (nestedDef != null) {
final String typeAttrib = sourceElement.getAttributeValue("type");
final String typeName = typeAttrib != null? typeAttrib : name;
final AntTypeId typeId = new AntTypeId(typeName);
nestedDef.setTypeId(typeId);
nestedDef.setClassName(elementClassName);
//nestedDef.setIsTask(false);
nestedDef.setDefiningElement(child);
file.registerCustomType(nestedDef);
nestedElements.put(typeId, nestedDef.getClassName());
}
}
}
}
}
final AntTypeId definedTypeId = new AntTypeId(getName());
if (myScriptDefinition == null) {
myScriptDefinition = new AntTypeDefinitionImpl(definedTypeId, thisClassName, true, false, attributes, nestedElements, this);
}
else {
myScriptDefinition.setTypeId(definedTypeId);
myScriptDefinition.setClassName(thisClassName);
myScriptDefinition.setIsTask(true);
myScriptDefinition.setDefiningElement(this);
}
final AntStructuredElement parent = getAntProject();
if (parent != null) {
parent.registerCustomType(myScriptDefinition);
}
// define itself as nested task for sequential
final AntAllTasksContainerImpl sequential = PsiTreeUtil.getChildOfType(this, AntAllTasksContainerImpl.class);
if (sequential != null) {
sequential.registerCustomType(myScriptDefinition);
for (final AntTypeId id : myScriptDefinition.getNestedElements()) {
sequential.registerCustomType(file.getBaseTypeDefinition(myScriptDefinition.getNestedClassName(id)));
}
}
}
}
@@ -1,653 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.config.AntConfigurationBase;
import com.intellij.lang.ant.misc.AntStringInterner;
import com.intellij.lang.ant.misc.PsiElementWithValueSetSpinAllocator;
import com.intellij.lang.ant.psi.*;
import com.intellij.lang.ant.psi.introspection.AntAttributeType;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.lang.ant.psi.introspection.AntTypeId;
import com.intellij.lang.ant.psi.introspection.impl.AntTypeDefinitionImpl;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiLock;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.*;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.InputStream;
import java.util.*;
import java.util.regex.Pattern;
public class AntStructuredElementImpl extends AntElementImpl implements AntStructuredElement {
private static final AntNameIdentifier ourNullIdentifier = new AntNameIdentifierImpl(null, null) {
@NonNls
public String getIdentifierName() {
return "AntNullIdentifier";
}
public boolean isValid() {
return true;
}
};
protected volatile AntTypeDefinition myDefinition;
private boolean myDefinitionCloned;
private volatile AntNameIdentifier myIdElement;
private volatile AntNameIdentifier myNameElement;
@NonNls
private volatile String myNameElementAttribute;
private int myLastFoundElementOffset = -1;
private AntElement myLastFoundElement;
private volatile boolean myIsImported;
private StringSetHolder myComputingAttrValue;
protected volatile boolean myInGettingChildren;
@NonNls private static final String ANTLIB_NS_PREFIX = "antlib:";
@NonNls private static final String ANTLIB_XML = "antlib.xml";
private static final Pattern $$_PATTERN = Pattern.compile("\\$\\$");
private AntStructuredElementImpl(final AntElement parent, final XmlTag sourceElement, @NonNls final String nameElementAttribute) {
super(parent, sourceElement);
myNameElementAttribute = AntStringInterner.intern(nameElementAttribute);
getIdElement();
getNameElement();
invalidateAntlibNamespace();
}
public AntStructuredElementImpl(final AntElement parent, final XmlTag sourceElement) {
this(parent, sourceElement, AntFileImpl.NAME_ATTR);
}
public AntStructuredElementImpl(final AntElement parent,
final XmlTag sourceElement,
final AntTypeDefinition definition,
@NonNls final String nameElementAttribute) {
this(parent, sourceElement, nameElementAttribute);
myDefinition = definition;
final AntTypeId id = new AntTypeId(sourceElement.getName());
if (definition != null) {
if (!definition.getTypeId().equals(id)) {
myDefinition = new AntTypeDefinitionImpl((AntTypeDefinitionImpl)myDefinition);
myDefinition.setTypeId(id);
myDefinitionCloned = true;
}
}
else {
/**
* This branch reloads of type definition in case if it could be
* registered during invalidation of the "antlib:..." namespace
*/
final AntFile file = getAntFile();
if (file != null) {
final AntTypeDefinition targetDef = file.getTargetDefinition();
final String className = targetDef != null? targetDef.getNestedClassName(id) : null;
if (className != null) {
myDefinition = file.getBaseTypeDefinition(className);
}
}
}
}
public AntStructuredElementImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition) {
this(parent, sourceElement, definition, AntFileImpl.NAME_ATTR);
}
public void acceptAntElementVisitor(@NotNull final AntElementVisitor visitor) {
visitor.visitAntStructuredElement(this);
}
@NotNull
public XmlTag getSourceElement() {
return (XmlTag)super.getSourceElement();
}
public String toString() {
@NonNls final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append("AntStructuredElement[");
builder.append(getSourceElement().getName());
builder.append("]");
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
public String getName() {
if (hasNameElement()) {
return computeAttributeValue(getNameElement().getIdentifierName());
}
if (hasIdElement()) {
return computeAttributeValue(getIdElement().getIdentifierName());
}
final XmlTag sourceElement = getSourceElement();
return sourceElement != null ? sourceElement.getName() : super.getName();
}
public PsiElement setName(@NotNull final String name) throws IncorrectOperationException {
try {
if (hasNameElement()) {
getNameElement().setIdentifierName(name);
}
else if (hasIdElement()) {
getIdElement().setIdentifierName(name);
}
return this;
}
finally {
clearCaches();
}
}
public boolean canRename() {
return super.canRename() && (hasNameElement() || hasIdElement());
}
public PsiElement findElementAt(int offset) {
synchronized (PsiLock.LOCK) {
if (offset != myLastFoundElementOffset || (myLastFoundElement != null && !myLastFoundElement.isValid())) {
final PsiElement foundElement = super.findElementAt(offset);
if (foundElement == null) {
return null;
}
myLastFoundElement = (AntElement)foundElement;
myLastFoundElementOffset = offset;
}
return myLastFoundElement;
}
}
public AntTypeDefinition getTypeDefinition() {
synchronized (PsiLock.LOCK) {
if (myDefinition != null && !myDefinitionCloned && myDefinition.isOutdated()) {
final AntTypeDefinition currentDef = getAntFile().getBaseTypeDefinition(myDefinition.getClassName());
if (currentDef != null) {
myDefinition = currentDef;
}
}
return myDefinition;
}
}
public void registerCustomType(final AntTypeDefinition def) {
synchronized (PsiLock.LOCK) {
AntTypeDefinition definition = getTypeDefinition();
if (definition != null) {
if (!myDefinitionCloned) {
definition = new AntTypeDefinitionImpl((AntTypeDefinitionImpl)definition);
myDefinition = definition;
myDefinitionCloned = true;
}
definition.registerNestedType(def.getTypeId(), def.getClassName());
}
getAntFile().registerCustomType(def);
}
}
public void unregisterCustomType(final AntTypeDefinition def) {
synchronized (PsiLock.LOCK) {
if (myDefinition != null && myDefinitionCloned) {
final AntTypeId typeId = def.getTypeId();
// for the same typeId there might be different classes registered
// so unregister only that type that is really registered as a nested within this element
final String registeredClassName = myDefinition.getNestedClassName(typeId);
if (registeredClassName != null && registeredClassName.equals(def.getClassName())) {
myDefinition.unregisterNestedType(typeId);
}
}
getAntFile().unregisterCustomType(def);
}
}
public boolean hasImportedTypeDefinition() {
return myIsImported;
}
void setImportedTypeDefinition(boolean imported) {
myIsImported = imported;
}
@Nullable
public PsiFile findFileByName(final String name) {
return findFileByName(name, "");
}
@Nullable
public PsiFile findFileByName(final String name, @Nullable final String baseDir) {
if (name == null) {
return null;
}
final AntFile antFile = getAntFile();
if (antFile == null) {
return null;
}
VirtualFile vFile = antFile.getContainingPath();
if (vFile == null) {
return null;
}
String projectPath = vFile.getPath();
String dir = baseDir;
if (dir == null) {
final AntProject project = antFile.getAntProject();
dir = project == null ? null : project.getBaseDir();
}
if (dir != null && dir.length() > 0) {
projectPath = new File(projectPath, dir).getAbsolutePath();
}
final String fileName = computeAttributeValue(name);
if (fileName == null) {
return null;
}
File file = new File(fileName);
if (!file.isAbsolute()) {
file = new File(projectPath, fileName);
}
vFile = LocalFileSystem.getInstance().findFileByPath(file.getAbsolutePath().replace(File.separatorChar, '/'));
if (vFile == null) {
return null;
}
return antFile.getViewProvider().getManager().findFile(vFile);
}
@Nullable
public String computeAttributeValue(final String value) {
if (value == null || value.indexOf('$') < 0) {
return value; // optimization
}
synchronized (PsiLock.LOCK) {
if (value != null) {
if (myComputingAttrValue == null || !myComputingAttrValue.contains(value)) {
try {
if (myComputingAttrValue == null) {
myComputingAttrValue = new StringSetHolder();
}
final AntConfigurationBase antConfig = AntConfigurationBase.getInstance(getProject());
myComputingAttrValue.add(value);
try {
final Set<Pair<PsiElement,String>> set = PsiElementWithValueSetSpinAllocator.alloc();
try {
return computeAttributeValue(value, set, antConfig);
}
finally {
PsiElementWithValueSetSpinAllocator.dispose(set);
}
}
catch (SpinAllocator.AllocatorExhaustedException e) {
return computeAttributeValue(value, new HashSet<Pair<PsiElement, String>>(), antConfig);
}
}
finally {
myComputingAttrValue.remove(value);
if (myComputingAttrValue.size() == 0) {
myComputingAttrValue.dispose();
myComputingAttrValue = null;
}
}
}
}
return null;
}
}
public boolean hasNameElement() {
return getNameElement() != ourNullIdentifier;
}
public boolean hasIdElement() {
return getIdElement() != ourNullIdentifier;
}
@NotNull
public List<String> getFileReferenceAttributes() {
final AntTypeDefinition typeDef = getTypeDefinition();
if (typeDef == null) {
return Collections.emptyList();
}
final String[] attribs = typeDef.getAttributes();
if (attribs.length == 0) {
return Collections.emptyList();
}
final List<String> fileRefAttributes = new ArrayList<String>(attribs.length);
for (String attrib : attribs) {
if (typeDef.getAttributeType(attrib) == AntAttributeType.FILE) {
fileRefAttributes.add(attrib);
}
}
return fileRefAttributes;
}
public boolean isTypeDefined() {
final AntTypeDefinition def = getTypeDefinition();
return def != null && def.getDefiningElement() instanceof AntTypeDefImpl;
}
public boolean isPresetDefined() {
final AntTypeDefinition def = getTypeDefinition();
return def != null && def.getClassName().startsWith(AntPresetDefImpl.ANT_PRESETDEF_NAME);
}
public void clearCaches() {
synchronized (PsiLock.LOCK) {
super.clearCaches();
myIdElement = null;
myNameElement = null;
myLastFoundElementOffset = -1;
myLastFoundElement = null;
myLastProcessedChildren = null;
invalidateAntlibNamespace();
}
}
public AntElement lightFindElementAt(int offset) {
synchronized (PsiLock.LOCK) {
if (offset == myLastFoundElementOffset) {
return myLastFoundElement;
}
}
return super.lightFindElementAt(offset);
}
public int getTextOffset() {
if (hasNameElement()) {
return getNameElement().getTextOffset();
}
if (hasIdElement()) {
return getIdElement().getTextOffset();
}
return super.getTextOffset();
}
protected AntElement[] getChildrenInner() {
synchronized (PsiLock.LOCK) {
if (!myInGettingChildren) {
myInGettingChildren = true;
try {
final List<AntElement> children = new ArrayList<AntElement>();
if (hasIdElement()) {
children.add(getIdElement());
}
if (hasNameElement()) {
children.add(getNameElement());
}
for (final PsiElement element : getSourceElement().getChildren()) {
if (element instanceof XmlElement) {
final AntElement antElement = AntElementFactory.createAntElement(this, (XmlElement)element);
if (antElement != null) {
children.add(antElement);
/*
if (antElement instanceof AntStructuredElement) {
antElement.getChildren();
}
*/
}
}
}
final int count = children.size();
return count > 0 ? children.toArray(new AntElement[count]) : AntElement.EMPTY_ARRAY;
}
finally {
myInGettingChildren = false;
}
}
}
return AntElement.EMPTY_ARRAY;
}
@NotNull
public AntElement[] getChildren() {
synchronized (PsiLock.LOCK) {
return fixUndefinedElements(super.getChildren());
}
}
private AntElement[] myLastProcessedChildren;
private AntElement[] fixUndefinedElements(final AntElement[] elements) {
if (myLastProcessedChildren == elements) {
return elements;
}
myLastProcessedChildren = elements;
if (isValid()) {
for (int i = 0; i < elements.length; i++) {
final AntElement element = elements[i];
if (element instanceof AntStructuredElement && element.isValid()) {
AntStructuredElement se = (AntStructuredElement)element;
if (se.getTypeDefinition() == null) {
final XmlTag sourceElement = se.getSourceElement();
se = (AntStructuredElement)AntElementFactory.createAntElement(this, sourceElement);
if (se != null && se.getTypeDefinition() != null) {
elements[i] = se;
}
}
}
}
}
return elements;
}
@NotNull
private AntNameIdentifier getIdElement() {
synchronized (PsiLock.LOCK) {
if (myIdElement == null) {
myIdElement = ourNullIdentifier;
final XmlTag se = getSourceElement();
if (se.isValid()) {
final XmlAttribute idAttr = se.getAttribute(AntFileImpl.ID_ATTR, null);
if (idAttr != null) {
final XmlAttributeValue valueElement = idAttr.getValueElement();
if (valueElement != null) {
final AntNameIdentifierImpl identifier = new AntNameIdentifierImpl(this, valueElement);
myIdElement = identifier;
getAntProject().registerRefId(identifier.getIdentifierName(), this);
}
}
}
}
return myIdElement;
}
}
@NotNull
private AntNameIdentifier getNameElement() {
synchronized (PsiLock.LOCK) {
if (myNameElement == null) {
myNameElement = ourNullIdentifier;
final XmlTag se = getSourceElement();
if (se.isValid()) {
final XmlAttribute nameAttr = se.getAttribute(myNameElementAttribute, null);
if (nameAttr != null) {
final XmlAttributeValue valueElement = nameAttr.getValueElement();
if (valueElement != null) {
myNameElement = new AntNameIdentifierImpl(this, valueElement);
}
}
}
}
return myNameElement;
}
}
@NonNls
protected String getNameElementAttribute() {
return myNameElementAttribute;
}
/**
* Cycle-safe computation of an attribute value with resolving properties.
*
* @param value
* @param elementStack
* @param antConfig
* @return
*/
private String computeAttributeValue(String value, final Set<Pair<PsiElement, String>> elementStack, final AntConfigurationBase antConfig) {
final Pair<PsiElement, String> resolveStackEntry = new Pair<PsiElement, String>(this, value);
elementStack.add(resolveStackEntry);
try {
int startProp = 0;
final AntFile self = getAntFile();
final AntFile antFile = null/*antConfig.getEffectiveContextFile(self)*/;
while ((startProp = value.indexOf("${", startProp)) >= 0) {
if (startProp > 0 && value.charAt(startProp - 1) == '$') {
// the '$' is escaped
startProp += 2;
continue;
}
final int endProp = value.indexOf('}', startProp + 2);
if (endProp <= startProp + 2) {
startProp += 2;
continue;
}
final String prop = value.substring(startProp + 2, endProp);
final Ref<String> resolvedValueRef = new Ref<String>(null);
final Ref<Boolean> shouldReturnOriginalValue = new Ref<Boolean>(Boolean.FALSE);
antFile.processAllProperties(prop, new Processor<AntProperty>() {
public boolean process(AntProperty antProperty) {
final String resolvedValue = antProperty.getValue(prop);
if (resolvedValue == null) {
return true;
}
if (elementStack.contains(new Pair<PsiElement, String>(antProperty, resolvedValue))) {
shouldReturnOriginalValue.set(Boolean.TRUE);
}
else {
resolvedValueRef.set(((AntStructuredElementImpl)antProperty).computeAttributeValue(resolvedValue, elementStack, antConfig));
}
return false;
}
});
if (shouldReturnOriginalValue.get()) {
return value; // prevent cycles
}
if (resolvedValueRef.get() == null) {
startProp += 2;
}
else {
if (resolvedValueRef.get().equals(value) /*prevent tail recursion*/) {
return value;
}
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append(value, 0, startProp);
builder.append(resolvedValueRef.get());
if (endProp < value.length() - 1) {
builder.append(value, endProp + 1, value.length());
}
final String substituted = builder.toString();
if (!substituted.equals(value)) {
value = substituted;
}
else {
startProp += 2;
}
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
}
if (value.indexOf("$$") >= 0) {
return $$_PATTERN.matcher(value).replaceAll("\\$");
}
return value;
}
finally {
elementStack.remove(resolveStackEntry);
}
}
private String getNamespace() {
return getSourceElement().getNamespace();
}
private void invalidateAntlibNamespace() {
final AntFile file = getAntFile();
if (file == null) return;
final ClassLoader loader = file.getClassLoader();
if (loader == null) return;
final String ns = getNamespace();
if (!ns.startsWith(ANTLIB_NS_PREFIX)) return;
final AntElement parent = getAntParent();
if (!(this instanceof AntProject)) {
if (parent instanceof AntStructuredElementImpl && ns.equals(((AntStructuredElementImpl)parent).getNamespace())) return;
}
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append(ns.substring(ANTLIB_NS_PREFIX.length()).replace('.', '/'));
builder.append('/');
builder.append(ANTLIB_XML);
final InputStream antlibStream = loader.getResourceAsStream(builder.toString());
if (antlibStream != null) {
AntTypeDefImpl.loadAntlibStream(antlibStream, this, ns);
}
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
private static final class StringSetHolder {
@NotNull
private Set<String> mySet;
private boolean myShouldDispose = true;
public StringSetHolder() {
try {
mySet = StringSetSpinAllocator.alloc();
}
catch (SpinAllocator.AllocatorExhaustedException e) {
mySet = new HashSet<String>();
myShouldDispose = false;
}
}
public boolean contains(String str) {
return mySet.contains(str);
}
public int size() {
return mySet.size();
}
public boolean add(final String s) {
return mySet.add(s);
}
public boolean remove(final String s) {
return mySet.remove(s);
}
public void dispose() {
if (myShouldDispose) {
StringSetSpinAllocator.dispose(mySet);
}
}
}
}
@@ -1,142 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.AntElementRole;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntElementVisitor;
import com.intellij.lang.ant.psi.AntProject;
import com.intellij.lang.ant.psi.AntTarget;
import com.intellij.psi.PsiLock;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.StringBuilderSpinAllocator;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class AntTargetImpl extends AntStructuredElementImpl implements AntTarget {
private AntTarget[] myDependsTargets;
public AntTargetImpl(AntElement parent, final XmlTag tag) {
super(parent, tag);
myDefinition = getAntFile().getTargetDefinition();
}
@NonNls
public String toString() {
@NonNls final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append("AntTarget:[");
builder.append(getName());
if (getDescription() != null) {
builder.append(" :");
builder.append(getDescription());
}
builder.append("]");
final AntTarget[] targets = getDependsTargets();
if (targets.length > 0) {
builder.append(" -> [");
for (AntTarget target : targets) {
builder.append(' ');
builder.append(target.getName());
}
builder.append(" ]");
}
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
public AntElementRole getRole() {
return AntElementRole.TARGET_ROLE;
}
public void acceptAntElementVisitor(@NotNull final AntElementVisitor visitor) {
visitor.visitAntTarget(this);
}
@NotNull
public String getQualifiedName() {
final AntProject project = getAntProject();
final String projectName = (project != null) ? project.getName() : null;
final String name = getName();
final String result = (projectName == null || projectName.length() == 0) ? name : projectName + '.' + name;
return (result == null) ? "" : result;
}
@Nullable
public String getDescription() {
return getSourceElement().getAttributeValue(AntFileImpl.DESCRIPTION_ATTR);
}
@Nullable
public String getConditionalPropertyName(final ConditionalAttribute attrib) {
final XmlAttribute propNameAttribute = getSourceElement().getAttribute(attrib.getXmlName(), null);
if (propNameAttribute != null) {
final XmlAttributeValue valueElement = propNameAttribute.getValueElement();
if (valueElement != null) {
return computeAttributeValue(valueElement.getValue());
}
}
return null;
}
@NotNull
public AntTarget[] getDependsTargets() {
synchronized (PsiLock.LOCK) {
if (myDependsTargets == null) {
final String depends = getSourceElement().getAttributeValue(AntFileImpl.DEPENDS_ATTR);
if (depends == null || depends.length() == 0) {
myDependsTargets = AntTarget.EMPTY_ARRAY;
}
else {
final AntProject project = getAntProject();
final List<AntTarget> targets = new ArrayList<AntTarget>();
for (final String name : depends.split(",|[\\s]+")) {
final AntTarget antTarget = project.getTarget(name);
if (antTarget != null) {
targets.add(antTarget);
}
}
myDependsTargets = targets.toArray(new AntTarget[targets.size()]);
}
}
return myDependsTargets;
}
}
public void setDependsTargets(@NotNull AntTarget[] targets) {
synchronized (PsiLock.LOCK) {
myDependsTargets = targets;
}
}
public void clearCaches() {
synchronized (PsiLock.LOCK) {
super.clearCaches();
myDependsTargets = null;
}
}
}
@@ -1,78 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.AntElementRole;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntElementVisitor;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.lang.ant.psi.AntTask;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.StringBuilderSpinAllocator;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class AntTaskImpl extends AntStructuredElementImpl implements AntTask {
public AntTaskImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition) {
super(parent, sourceElement, definition);
}
public AntTaskImpl(final AntElement parent,
final XmlTag sourceElement,
final AntTypeDefinition definition,
@NonNls final String nameElementAttribute) {
super(parent, sourceElement, definition, nameElementAttribute);
}
public void acceptAntElementVisitor(@NotNull final AntElementVisitor visitor) {
visitor.visitAntTask(this);
}
public String toString() {
@NonNls final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append("AntTask[");
builder.append(getSourceElement().getName());
builder.append("]");
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
public AntElementRole getRole() {
return (!isMacroDefined() && !isPresetDefined() && !isTypeDefined()) ? AntElementRole.TASK_ROLE : AntElementRole.USER_TASK_ROLE;
}
@Nullable
public AntStructuredElement getAntParent() {
return (AntStructuredElement)super.getAntParent();
}
public boolean isMacroDefined() {
final AntTypeDefinition def = getTypeDefinition();
return def != null && def.getClassName().startsWith(AntMacroDefImpl.ANT_MACRODEF_NAME);
}
public boolean isScriptDefined() {
final AntTypeDefinition def = getTypeDefinition();
return def != null && def.getClassName().startsWith(AntScriptDefImpl.ANT_SCRIPTDEF_NAME);
}
}
@@ -1,41 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.psi.PsiLock;
import com.intellij.psi.xml.XmlTag;
/**
* @author Eugene Zhuravlev
* Date: May 14, 2007
*/
public class AntTimestampFormatImpl extends AntStructuredElementImpl{
public AntTimestampFormatImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition) {
super(parent, sourceElement, definition, AntFileImpl.PROPERTY);
}
public void clearCaches() {
synchronized (PsiLock.LOCK) {
super.clearCaches();
final AntElement parent = getAntParent();
if (parent != null) {
parent.clearCaches();
}
}
}
}
@@ -1,667 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.config.impl.AntResourcesClassLoader;
import com.intellij.lang.ant.psi.*;
import com.intellij.lang.ant.psi.impl.reference.AntRefIdReference;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.lang.ant.psi.introspection.AntTypeId;
import com.intellij.lang.ant.psi.introspection.impl.AntTypeDefinitionImpl;
import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.LocalTimeCounter;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.containers.ObjectCache;
import org.apache.tools.ant.PathTokenizer;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.TaskContainer;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
public class AntTypeDefImpl extends AntTaskImpl implements AntTypeDef {
@NonNls private static final String CLASSPATH_ATTR = "classpath";
@NonNls private static final String URI_ATTR = "uri";
@NonNls private static final String RESOURCE_ATTR = "resource";
@NonNls private static final String FILE_ATTR = AntFileImpl.FILE_ATTR;
@NonNls private static final String CLASSNAME_ATTR = "classname";
@NonNls private static final String ADAPTER_ATTR = "adapter";
@NonNls private static final String ADAPTTO_ATTR = "adaptto";
@NonNls private static final String BASEDIR_ANT_REFERENCE = "${" + AntFileImpl.BASEDIR_ATTR + "}";
private static final ClassLoaderCache LOADERS_CACHE = new ClassLoaderCache();
private AntTypeDefinition[] myNewDefinitions;
private boolean myClassesLoaded;
private String myLocalizedError;
public AntTypeDefImpl(final AntElement parent, final XmlTag sourceElement, final AntTypeDefinition definition) {
super(parent, sourceElement, definition);
getDefinitions();
}
public String toString() {
@NonNls final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append("AntTypeDef[");
builder.append(getSourceElement().getName());
builder.append("]");
final AntTypeDefinition[] defs = getDefinitions();
if (defs.length != 0) {
builder.append(" classes={");
builder.append(defs[0].getClassName());
for (int i = 1; i < defs.length; ++i) {
builder.append(',');
builder.append(defs[i].getClassName());
}
builder.append("}");
}
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
@NotNull
public List<String> getFileReferenceAttributes() {
final List<String> attribs = super.getFileReferenceAttributes();
final String cp = getClassPath();
if (cp != null && cp.length() > 0 && !cp.contains(";") && !cp.contains(":")) {
// only single-entry classpath is accepted
final List<String> _attribs = new ArrayList<String>(attribs.size() + 1);
_attribs.addAll(attribs);
_attribs.add(CLASSPATH_ATTR);
return _attribs;
}
return attribs;
}
@Nullable
public String getDefinedName() {
return computeAttributeValue(getSourceElement().getAttributeValue(getNameElementAttribute()));
}
@Nullable
public String getClassName() {
return computeAttributeValue(getSourceElement().getAttributeValue(CLASSNAME_ATTR));
}
@Nullable
public String getAdapterName() {
return computeAttributeValue(getSourceElement().getAttributeValue(ADAPTER_ATTR));
}
@Nullable
public String getAdaptToName() {
return computeAttributeValue(getSourceElement().getAttributeValue(ADAPTTO_ATTR));
}
@Nullable
public String getClassPath() {
return computeAttributeValue(getSourceElement().getAttributeValue(CLASSPATH_ATTR));
}
@Nullable
public String getUri() {
return computeAttributeValue(getSourceElement().getAttributeValue(URI_ATTR));
}
@Nullable
public String getFile() {
return computeAttributeValue(getSourceElement().getAttributeValue(FILE_ATTR));
}
@Nullable
public String getResource() {
return computeAttributeValue(getSourceElement().getAttributeValue(RESOURCE_ATTR));
}
@NonNls
@Nullable
public String getFormat() {
return computeAttributeValue(getSourceElement().getAttributeValue("format"));
}
public void clearCaches() {
synchronized (PsiLock.LOCK) {
super.clearCaches();
clearClassesCache();
final AntFile file = getAntFile();
if (file != null) {
file.clearCaches();
}
}
}
@NotNull
public AntTypeDefinition[] getDefinitions() {
synchronized (PsiLock.LOCK) {
if (myNewDefinitions == null || (!typesLoaded() && myLocalizedError == null /*don't give up loading until the error occurres or types are loaded*/)) {
myNewDefinitions = AntTypeDefinition.EMPTY_ARRAY;
final String classname = getClassName();
if (classname != null) {
final AntStructuredElement parent = getAntParent();
final AntFile antFile = parent != null? parent.getAntFile() : null;
loadClass(antFile, classname, getDefinedName(), getUri(),getAntParent());
}
else {
final String resource = getResource();
if (resource != null) {
loadResource(resource);
}
else {
final String file = getFile();
if (file != null) {
loadFile(file);
}
}
}
}
return myNewDefinitions;
}
}
public boolean typesLoaded() {
return myClassesLoaded;
}
public void clearClassesCache() {
synchronized(PsiLock.LOCK) {
if (myNewDefinitions != null) {
final AntStructuredElement parent = getAntParent();
if (parent != null) {
final AntProject antProject = !(parent instanceof AntProject)? parent.getAntProject() : null;
for (final AntTypeDefinition def : myNewDefinitions) {
parent.unregisterCustomType(def);
if (antProject != null) {
antProject.unregisterCustomType(def);
}
}
}
myNewDefinitions = null;
//myClassesLoaded = false;
}
}
}
@Nullable
public String getLocalizedError() {
return myLocalizedError;
}
public void acceptAntElementVisitor(@NotNull final AntElementVisitor visitor) {
visitor.visitAntTypedef(this);
}
static void loadAntlibStream(@NotNull final InputStream antlibStream, final AntStructuredElement element, final String ns) {
final String nsPrefix = element.getSourceElement().getPrefixByNamespace(ns);
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
int nextByte;
while ((nextByte = antlibStream.read()) >= 0) {
builder.append((char)nextByte);
}
antlibStream.close();
final XmlFile xmlFile = (XmlFile)createDummyFile("dummy.xml", StdFileTypes.XML, builder, element.getManager());
final XmlDocument document = xmlFile.getDocument();
if (document == null) return;
final XmlTag rootTag = document.getRootTag();
if (rootTag == null) return;
for (final XmlTag tag : rootTag.getSubTags()) {
if (nsPrefix != null && nsPrefix.length() > 0) {
try {
tag.setName(nsPrefix + ':' + tag.getLocalName());
}
catch (IncorrectOperationException e) {
continue;
}
}
final AntElement newElement = AntElementFactory.createAntElement(element, tag);
if (newElement instanceof AntTypeDef) {
for (final AntTypeDefinition def : ((AntTypeDef)newElement).getDefinitions()) {
if (element instanceof AntTypeDefImpl) {
final AntTypeDefImpl td = ((AntTypeDefImpl)element);
final AntTypeDefinition[] defs = td.myNewDefinitions != null ? td.myNewDefinitions : AntTypeDefinition.EMPTY_ARRAY;
td.myNewDefinitions = ArrayUtil.append(defs, def);
((AntTypeDefinitionImpl)def).setDefiningElement(td);
}
}
}
}
}
catch (IOException e) {
if (element instanceof AntTypeDefImpl) {
final AntTypeDefImpl td = ((AntTypeDefImpl)element);
td.myClassesLoaded = false;
td.myLocalizedError = e.getLocalizedMessage();
}
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
private void loadPropertiesStream(final InputStream propStream, final AntStructuredElement element) {
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
int nextByte;
while ((nextByte = propStream.read()) >= 0) {
builder.append((char)nextByte);
}
propStream.close();
final PropertiesFile propFile =
(PropertiesFile)createDummyFile("dummy.properties", StdFileTypes.PROPERTIES, builder, element.getManager());
final AntStructuredElement parent = getAntParent();
final AntFile antFile = parent != null? parent.getAntFile() : null;
for (final IProperty property : propFile.getProperties()) {
loadClass(antFile, property.getValue(), property.getUnescapedKey(), getUri(),getAntParent());
}
}
catch (IOException e) {
if (element instanceof AntTypeDefImpl) {
final AntTypeDefImpl td = ((AntTypeDefImpl)element);
td.myClassesLoaded = false;
td.myLocalizedError = e.getLocalizedMessage();
}
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
private boolean isXmlFormat(@NonNls @NotNull final String resourceOfFileName) {
@NonNls final String format = getFormat();
if (format != null) {
return format.equals("xml");
}
return resourceOfFileName.endsWith(".xml");
}
private void loadResource(@NotNull final String resource) {
ClassLoader loader = getClassLoader(getClassPathUrls());
if (loader != null) {
final InputStream stream = loader.getResourceAsStream(resource);
if (stream != null) {
myClassesLoaded = true;
if (!isXmlFormat(resource)) {
loadPropertiesStream(stream, this);
}
else {
loadAntlibStream(stream, this, getUri());
}
}
}
}
private void loadFile(final String file) {
final PsiFile psiFile = findFileByName(file, null);
if (psiFile != null) {
final VirtualFile vf = psiFile.getVirtualFile();
if (vf != null) {
try {
final InputStream stream = vf.getInputStream();
if (stream != null) {
myClassesLoaded = true;
if (!isXmlFormat(file)) {
loadPropertiesStream(stream, this);
}
else {
loadAntlibStream(stream, this, getUri());
}
}
}
catch (IOException e) {
//ignore
}
}
}
}
private AntTypeDefinitionImpl loadClass(final @Nullable AntFile antFile,
@Nullable final String classname,
@Nullable final String name,
@Nullable final String uri,
final AntStructuredElement parent) {
if (classname == null || name == null || name.length() == 0) {
return null;
}
ProgressManager.checkCanceled();
final List<URL> urls = getClassPathUrls();
Class clazz = null;
final ClassLoader loader = getClassLoader(urls);
if (loader != null) {
try {
clazz = loader.loadClass(classname);
}
catch (ClassNotFoundException e) {
myLocalizedError = e.getLocalizedMessage();
clazz = null;
}
catch (NoClassDefFoundError e) {
myLocalizedError = e.getLocalizedMessage();
clazz = null;
}
catch (UnsupportedClassVersionError e) {
myLocalizedError = e.getLocalizedMessage();
clazz = null;
}
}
final String nsPrefix = (uri == null) ? null : getSourceElement().getPrefixByNamespace(uri);
final AntTypeId id = (nsPrefix == null) ? new AntTypeId(name) : new AntTypeId(name, nsPrefix);
AntTypeDefinitionImpl def;
if (clazz == null) {
def = new AntTypeDefinitionImpl(id, classname, isTask(), false);
}
else {
myClassesLoaded = true;
final boolean isTask = isTask(clazz);
def = (AntTypeDefinitionImpl)AntFileImpl.createTypeDefinition(id, clazz, isTask);
if (def == null) { // can be null if failed to introspect the class for some reason
def = new AntTypeDefinitionImpl(id, classname, isTask, isAssignableFrom(TaskContainer.class.getName(), clazz));
}
else {
fixNestedDefinitions(def);
}
def.setIsProperty(isAssignableFrom(org.apache.tools.ant.taskdefs.Property.class.getName(), clazz));
}
myNewDefinitions = ArrayUtil.append(myNewDefinitions, def);
def.setDefiningElement(this);
if (parent != null) {
if (!(parent instanceof AntProject)) {
// make custom definition available at project level first
final AntProject antProject = parent.getAntProject();
if (antProject != null) {
antProject.registerCustomType(def);
}
}
parent.registerCustomType(def);
}
else {
if (antFile != null) {
antFile.registerCustomType(def);
}
}
if (antFile != null) {
for (final AntTypeId typeId : def.getNestedElements()) {
final String nestedClassName = def.getNestedClassName(typeId);
AntTypeDefinitionImpl nestedDef = (AntTypeDefinitionImpl)antFile.getBaseTypeDefinition(nestedClassName);
if (nestedDef == null) {
nestedDef = loadClass(antFile, nestedClassName, typeId.getName(), uri, null);
if (nestedDef != null) {
def.registerNestedType(nestedDef.getTypeId(), nestedDef.getClassName());
}
}
}
}
return def;
}
private void fixNestedDefinitions(final AntTypeDefinitionImpl def) {
// hack to overcome problems with poorly written custom tasks.
// For example: net.sf.antcontrib.logic.ForTask.createSequential() is defined to
// return java.langObject instead of org.apache.tools.ant.taskdefs.Sequential
for (AntTypeId nestedTypeId : def.getNestedElements()) {
final String className = def.getNestedClassName(nestedTypeId);
if (CommonClassNames.JAVA_LANG_OBJECT.equals(className)) {
// check if such typeId is already mapped correct the definition's nested element
for (AntTypeDefinition typeDefinition : getAntFile().getBaseTypeDefinitions()) {
if (nestedTypeId.equals(typeDefinition.getTypeId()) && !CommonClassNames.JAVA_LANG_OBJECT.equals(typeDefinition.getClassName())) {
def.registerNestedType(nestedTypeId, typeDefinition.getClassName());
break;
}
}
}
}
}
private boolean isTask(final Class clazz) {
if (isTask()) { // in taskdef, the adapter is always set to Task
return true;
}
final String adaptto = getAdaptToName();
if (adaptto != null && isAssignableFrom(adaptto, clazz)) {
return isAssignableFrom(Task.class.getName(), clazz);
}
final String adapter = getAdapterName();
if (adapter != null) {
try {
final Class adapterClass = clazz.getClassLoader().loadClass(adapter);
return isAssignableFrom(Task.class.getName(), adapterClass);
}
catch (ClassNotFoundException ignored) {
}
catch (NoClassDefFoundError ignored) {
}
catch (UnsupportedClassVersionError ignored) {
}
}
return isAssignableFrom(Task.class.getName(), clazz);
}
private static boolean isAssignableFrom(final String baseClassName, final Class clazz) {
try {
final ClassLoader loader = clazz.getClassLoader();
if (loader != null) {
final Class baseClass = loader.loadClass(baseClassName);
return baseClass.isAssignableFrom(clazz);
}
}
catch (ClassNotFoundException ignored) {
}
return false;
}
private List<URL> getClassPathUrls() {
final List<URL> urls = getClassPathLocalUrls();
AntElement parent = getAntParent();
while (parent != null && !(parent instanceof AntProject)) {
if (parent instanceof AntTypeDefImpl) {
urls.addAll(((AntTypeDefImpl)parent).getClassPathLocalUrls());
}
parent = parent.getAntParent();
}
return urls;
}
private List<URL> getClassPathLocalUrls() {
final List<URL> urls = new ArrayList<URL>();
final String baseDir = computeAttributeValue(BASEDIR_ANT_REFERENCE);
// check classpath attribute
final String classpath = getClassPath();
if (classpath != null) {
final PathTokenizer tokenizer = new PathTokenizer(classpath);
while (tokenizer.hasMoreTokens()) {
addUrl(baseDir, urls, tokenizer.nextToken());
}
}
final List<File> files = new ArrayList<File>();
final HashSet<AntFilesProvider> processed = new HashSet<AntFilesProvider>(); // aux collection
// check 'classpathref'
for (PsiReference reference : getReferences()) {
ProgressManager.checkCanceled();
if (reference instanceof AntRefIdReference) {
final PsiElement resolved = reference.resolve();
if (resolved instanceof AntFilesProvider) {
files.addAll(((AntFilesProvider)resolved).getFiles(processed));
}
}
}
// check nested elements
for (AntElement antElement : getChildren()) {
ProgressManager.checkCanceled();
if (antElement instanceof AntFilesProvider) {
files.addAll(((AntFilesProvider)antElement).getFiles(processed));
}
}
for (File file : files) {
try {
//urls.add(file.toURL());
// toURL() implementation invokes File.isDirectory() which, if called too often, may cause performance problems
urls.add(toLocalURL(file));
}
catch (MalformedURLException e) {
}
}
return urls;
}
private static URL toLocalURL(final File file) throws MalformedURLException {
return new URL("file", "", FileUtil.toSystemIndependentName(file.getPath()));
}
private static void addUrl(final String baseDir, final List<URL> urls, final String path) {
if (path != null) {
try {
File file = new File(path);
if (file.isAbsolute()) {
urls.add(toLocalURL(file));
}
else {
if (baseDir != null) {
urls.add(toLocalURL(new File(baseDir, path)));
}
}
}
catch (MalformedURLException ignored) {
}
}
}
@Nullable
private ClassLoader getClassLoader(final List<URL> urls) {
final AntFile file = getAntFile();
final ClassLoader parentLoader = file != null ? file.getClassLoader() : null;
if (urls.size() == 0) {
return parentLoader;
}
final ClassLoader cached = LOADERS_CACHE.getClassLoader(urls);
if (cached != null && parentLoader == cached.getParent()) {
return cached;
}
final AntResourcesClassLoader loader = new AntResourcesClassLoader(urls, parentLoader, false, false);
LOADERS_CACHE.setClassLoader(urls, loader);
return loader;
}
private boolean isTask() {
return "taskdef".equals(getSourceElement().getName());
}
private static PsiFile createDummyFile(@NonNls final String name,
final LanguageFileType type,
final CharSequence str,
final PsiManager manager) {
return PsiFileFactory.getInstance(manager.getProject())
.createFileFromText(name, type, str, LocalTimeCounter.currentTime(), false, false);
}
private static class CacheKey {
public static final URL[] EMPTY_URL_ARRAY = new URL[0];
private final List<URL> myUrls;
private final int myHashCode;
public CacheKey(@NotNull final List<URL> urls) {
myUrls = urls;
int hashCode = 1;
for (URL url : urls) {
hashCode = 31 * hashCode + url.getPath().hashCode();
}
myHashCode = hashCode;
}
public final int hashCode() {
return myHashCode;
}
public final boolean equals(Object obj) {
if (!(obj instanceof CacheKey)) {
return false;
}
final CacheKey entry = (CacheKey)obj;
final List<URL> urls = myUrls;
final List<URL> thatUrls = entry.myUrls;
if (urls.size() != thatUrls.size()) {
return false;
}
final Iterator<URL> urlsIt = urls.iterator();
final Iterator<URL> thatUrlsIt = thatUrls.iterator();
while (urlsIt.hasNext()) {
if (!FileUtil.pathsEqual(urlsIt.next().getPath(), thatUrlsIt.next().getPath())) {
return false;
}
}
return true;
}
}
private static class ClassLoaderCache extends ObjectCache<CacheKey, SoftReference<ClassLoader>> {
public ClassLoaderCache() {
super(256);
}
@Nullable
public final synchronized ClassLoader getClassLoader(@NotNull final List<URL> urls) {
final CacheKey key = new CacheKey(urls);
final SoftReference<ClassLoader> ref = tryKey(key);
final ClassLoader result = (ref == null) ? null : ref.get();
if (result == null && ref != null) {
remove(key);
}
return result;
}
public final synchronized void setClassLoader(@NotNull final List<URL> urls, @NotNull final ClassLoader loader) {
cacheObject(new CacheKey(urls), new SoftReference<ClassLoader>(loader));
}
}
}
@@ -1,232 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl;
import com.intellij.lang.ant.psi.*;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import java.util.*;
/**
* @author Eugene Zhuravlev
* Date: Apr 13, 2007
*/
public class PropertiesBuilder extends AntElementVisitor {
private static final Logger LOG = Logger.getInstance("#com.intellij.lang.ant.psi.impl.PropertiesBuilder");
@NotNull private final AntFile myPropertyHolder;
private final Set<AntTarget> myVisitedTargets = new HashSet<AntTarget>();
private final Set<AntFile> myVisitedFiles = new HashSet<AntFile>();
private final Map<AntProject, List<Runnable>> myPostponedProcessing = new HashMap<AntProject, List<Runnable>>();
private final List<PsiFile> myDependentFiles = new ArrayList<PsiFile>();
private PropertiesBuilder(@NotNull AntFile propertyHolder) {
myPropertyHolder = propertyHolder;
}
@Override public void visitAntTypedef(final AntTypeDef def) {
// at this point all properties used in classpath for this typedef must be defined
// so to make sure the class set is complete, need to reload classes here
def.clearClassesCache();
def.getDefinitions();
}
@Override public void visitAntFile(final AntFile antFile) {
if (!myVisitedFiles.contains(antFile)) {
myVisitedFiles.add(antFile);
final AntProject project = antFile.getAntProject();
if (project != null) {
project.acceptAntElementVisitor(this);
((AntProjectImpl)project).clearImports();
}
}
}
@Override public void visitAntTask(final AntTask task) {
if (task instanceof AntProperty) {
visitAntProperty((AntProperty)task);
}
else {
super.visitAntTask(task);
}
}
public void visitAntStructuredElement(final AntStructuredElement element) {
if (element instanceof AntFilesProviderImpl) {
// need to clear cached files here
// because they might be cached at the moment when not all properties were loaded (e.g. because of antProject.getChildren())
// and thus not all paths might resolve
((AntFilesProviderImpl)element).clearCachedFiles();
}
super.visitAntStructuredElement(element);
}
@Override public void visitAntProject(final AntProject antProject) {
final Set<AntTarget> projectTargets = new LinkedHashSet<AntTarget>();
for (PsiElement child : antProject.getChildren()) {
if (child instanceof AntElement) {
if (child instanceof AntTarget) {
final AntTarget antTarget = (AntTarget)child;
if (antProject.equals(antTarget.getAntProject())) {
// heuristic: do not collect imported targets
projectTargets.add(antTarget);
}
}
else {
((AntElement)child).acceptAntElementVisitor(this);
}
}
}
final AntTarget entryTarget = antProject.getDefaultTarget();
if (entryTarget != null) {
entryTarget.acceptAntElementVisitor(this);
}
projectTargets.removeAll(myVisitedTargets);
// process unvisited targets
for (AntTarget antTarget : projectTargets) {
antTarget.acceptAntElementVisitor(this);
}
// process postponed targets
final List<Runnable> list = myPostponedProcessing.get(antProject);
if (list != null) {
for (Runnable runnable : list) {
runnable.run();
}
myPostponedProcessing.remove(antProject);
}
}
@Override public void visitAntProperty(final AntProperty antProperty) {
final PropertiesFile propertiesFile = antProperty.getPropertiesFile();
if (propertiesFile != null) {
myDependentFiles.add(propertiesFile.getContainingFile());
}
final String environment = antProperty.getEnvironment();
if (environment != null) {
myPropertyHolder.addEnvironmentPropertyPrefix(environment);
}
final String[] names = antProperty.getNames();
if (names != null) {
for (String name : names) {
myPropertyHolder.setProperty(name, antProperty);
}
}
}
@Override public void visitAntTarget(final AntTarget target) {
if (myVisitedTargets.contains(target)) {
return;
}
myVisitedTargets.add(target);
final AntTarget[] dependsTargets = target.getDependsTargets();
for (AntTarget dependsTarget : dependsTargets) {
dependsTarget.acceptAntElementVisitor(this);
}
final String ifProperty = target.getConditionalPropertyName(AntTarget.ConditionalAttribute.IF);
if (ifProperty != null && myPropertyHolder.getProperty(ifProperty) == null) {
postponeTargetVisiting(target);
return; // skip target because 'if' property not defined
}
final String unlessProperty = target.getConditionalPropertyName(AntTarget.ConditionalAttribute.UNLESS);
if (unlessProperty != null && myPropertyHolder.getProperty(unlessProperty) != null) {
postponeTargetVisiting(target);
return; // skip target because 'unless' property is defined
}
visitTargetChildren(target);
}
private void postponeTargetVisiting(final AntTarget target) {
final AntProject antProject = target.getAntProject();
List<Runnable> list = myPostponedProcessing.get(antProject);
if (list == null) {
list = new ArrayList<Runnable>();
myPostponedProcessing.put(antProject, list);
}
list.add(new Runnable() {
public void run() {
visitTargetChildren(target);
}
});
}
private void visitTargetChildren(final AntTarget target) {
for (PsiElement child : target.getChildren()) {
if (child instanceof AntElement) {
((AntElement)child).acceptAntElementVisitor(this);
}
}
}
@Override public void visitAntImport(final AntImport antImport) {
final AntFile antFile = antImport.getImportedFile();
if (antFile != null) {
myDependentFiles.add(antFile);
visitAntFile(antFile);
}
}
public static List<PsiFile> defineProperties(AntFile file) {
final AntProject project = file.getAntProject();
LOG.assertTrue(project != null);
final PropertiesBuilder builder = new PropertiesBuilder(file);
file.acceptAntElementVisitor(builder);
/*
for (AntTarget target : builder.myVisitedTargets) {
if (target instanceof AntTargetImpl) {
definePseudoProperties((AntTargetImpl)target);
}
}
*/
return builder.myDependentFiles;
}
/*
private static void definePseudoProperties(final AntTargetImpl target) {
final XmlTag se = target.getSourceElement();
XmlAttribute propNameAttribute = se.getAttribute(AntFileImpl.IF_ATTR, null);
if (propNameAttribute == null) {
propNameAttribute = se.getAttribute(AntFileImpl.UNLESS_ATTR, null);
}
if (propNameAttribute != null) {
final XmlAttributeValue valueElement = propNameAttribute.getValueElement();
if (valueElement != null) {
final String value = target.computeAttributeValue(valueElement.getValue());
final AntFile propertyHolder = target.getAntFile();
if (propertyHolder.getProperty(value) == null) {
target.setPropertyDefinitionElement(valueElement);
propertyHolder.setExternalProperty(value, target);
}
}
}
}
*/
}
@@ -1,64 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
/**
* Ant attribute reference serves only for completion.
*/
public class AntAttributeReference extends AntGenericReference {
public AntAttributeReference(final AntStructuredElement element,
final String str,
final TextRange textRange,
final XmlAttribute attribute) {
super(element, str, textRange, attribute);
}
public AntStructuredElement getElement() {
return (AntStructuredElement)super.getElement();
}
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
return null;
}
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
return null;
}
public PsiElement resolve() {
return null;
}
@NotNull
public Object[] getVariants() {
final AntTypeDefinition def = getElement().getTypeDefinition();
return (def == null) ? EMPTY_ARRAY : def.getAttributes();
}
public boolean shouldBeSkippedByAnnotator() {
return true;
}
}
@@ -1,83 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference;
import com.intellij.lang.ant.AntElementRole;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.impl.AntElementImpl;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNamedElement;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public class AntElementCompletionWrapper extends AntElementImpl implements PsiNamedElement {
private final String myName;
private final Project myProject;
private final AntElementRole myRole;
public AntElementCompletionWrapper(final AntElement parent, final String name, @NotNull final Project project, final AntElementRole role) {
super(parent, null);
myName = name;
myProject = project;
myRole = role;
}
public final String getText() {
return getName();
}
public boolean equals(final Object that) {
if (this == that) {
return true;
}
if (that instanceof AntElementCompletionWrapper) {
return myName.equals(((AntElementCompletionWrapper)that).myName);
}
return false;
}
public int hashCode() {
return myName.hashCode();
}
public final String getName() {
return myName;
}
@NotNull
public Project getProject() {
return myProject;
}
public AntElementRole getRole() {
return myRole;
}
public boolean isValid() {
return true;
}
public boolean isPhysical() {
return false;
}
public PsiElement setName(@NonNls @NotNull final String name) throws IncorrectOperationException {
throw new IncorrectOperationException("Can't rename ant completion element");
}
}
@@ -1,182 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference;
import com.intellij.lang.ant.AntElementRole;
import com.intellij.lang.ant.misc.PsiElementSetSpinAllocator;
import com.intellij.lang.ant.psi.*;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.lang.ant.psi.introspection.AntTypeId;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashSet;
import java.util.Set;
public class AntElementNameReference extends AntGenericReference {
public AntElementNameReference(final AntStructuredElement element) {
super(element);
}
public AntElementNameReference(final AntStructuredElement element, final XmlAttribute attr) {
super(element, attr);
}
public AntStructuredElement getElement() {
return (AntStructuredElement)super.getElement();
}
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
final AntStructuredElement element = getElement();
final AntTypeDefinition typeDef = element.getTypeDefinition();
if (typeDef == null) return element;
if (!(element instanceof AntTask)) {
final AntStructuredElement defElement = (AntStructuredElement)typeDef.getDefiningElement();
if (defElement != null && (defElement instanceof AntPresetDef || ((defElement.getParent() instanceof AntMacroDef || defElement.getParent() instanceof AntScriptDef) && "element".equals(defElement.getSourceElement().getName())))) {
// renaming macrodef's or scriptdef's nested element
element.getSourceElement().setName(newElementName);
}
}
else {
AntTask task = (AntTask)element;
if (task.isMacroDefined() || task.isScriptDefined() || task.isPresetDefined() || task.isTypeDefined()) {
final XmlAttribute attr = getAttribute();
if (attr == null) {
// renaming macrodef, presetdef or typedef/taskdef itself
task.getSourceElement().setName(newElementName);
}
else {
attr.setName(newElementName);
}
}
}
return element;
}
@Nullable
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
if (element instanceof AntStructuredElement) {
return handleElementRename(((AntStructuredElement)element).getName());
}
return getElement();
}
public PsiElement resolveInner() {
final AntStructuredElement element = getElement();
final AntTypeDefinition elementDef = element.getTypeDefinition();
if (elementDef != null) {
final PsiElement definingElement = elementDef.getDefiningElement();
if (element.isPresetDefined() || element.isTypeDefined()) {
return definingElement;
}
if (!(element instanceof AntTask)) {
return (definingElement == null) ? findClass(elementDef, element) : definingElement;
}
AntTask task = (AntTask)element;
if (task.isMacroDefined() || task.isScriptDefined()) {
final XmlAttribute attr = getAttribute();
if (definingElement != null && attr != null) {
final String attribName = attr.getName();
for (PsiElement child : definingElement.getChildren()) {
if (child instanceof AntStructuredElement && attribName.equals(((AntStructuredElement)child).getName())) {
return child;
}
}
}
return definingElement;
}
return findClass(elementDef, element);
}
return null;
}
public boolean shouldBeSkippedByAnnotator() {
return true;
}
@NotNull
public Object[] getVariants() {
if (getAttribute() != null) {
return EMPTY_ARRAY; // scriptdef or mactodef params will be handled by XML implementation
}
final AntStructuredElement parent = (AntStructuredElement)getElement().getAntParent();
if (parent == null) {
return EMPTY_ARRAY;
}
AntTypeDefinition def = parent.getTypeDefinition();
if (def == null) {
def = parent.getAntProject().getTypeDefinition();
if (def == null) {
return EMPTY_ARRAY;
}
}
final AntFile antFile = parent.getAntFile();
final Project project = antFile.getProject();
final Set<PsiElement> ids = PsiElementSetSpinAllocator.alloc();
try {
for (final AntTypeId id : def.getNestedElements()) {
ids.add(new AntElementCompletionWrapper(parent, id.getName() + " ", project, AntElementRole.TASK_ROLE));
}
if (def.isAllTaskContainer()) {
new Object() {
final Set<AntFile> processedFiles = new HashSet<AntFile>();
final Set<AntTypeId> processedTypes = new HashSet<AntTypeId>();
void walkFiles(AntFile file) {
if (processedFiles.contains(file)) {
return;
}
processedFiles.add(file);
for (final AntTypeDefinition _def : file.getBaseTypeDefinitions()) {
if (_def.isTask()) {
final AntTypeId typeId = _def.getTypeId();
if (!processedTypes.contains(typeId)) {
processedTypes.add(typeId);
ids.add(new AntElementCompletionWrapper(parent, typeId.getName() + " ", project, AntElementRole.TASK_ROLE));
}
}
}
for (AntFile imported : file.getAntProject().getImportedFiles()) {
walkFiles(imported);
}
}
}.walkFiles(antFile);
}
return ArrayUtil.toObjectArray(ids);
}
finally {
PsiElementSetSpinAllocator.dispose(ids);
}
}
@Nullable
private static PsiElement findClass(final AntTypeDefinition elementDef, final AntStructuredElement element) {
final String clazz = elementDef.getClassName();
return JavaPsiFacade.getInstance(element.getProject()).findClass(clazz, GlobalSearchScope.allScope(element.getProject()));
}
}
@@ -1,62 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference;
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.lang.ant.AntElementRole;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
public class AntEndElementNameReference extends AntElementNameReference {
private final TextRange myRange;
private final boolean myIsTagClosed;
public AntEndElementNameReference(final AntStructuredElement element, TextRange range, final boolean isClosed) {
super(element);
myRange = range;
myIsTagClosed = isClosed;
}
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
return getElement();
}
@NotNull
public LookupElement[] getVariants() {
final AntStructuredElement element = getElement();
final XmlTag xmlTag = element.getSourceElement();
final String completionText = myIsTagClosed ? element.getSourceElement().getName() : element.getSourceElement().getName() + ">";
final AntElementCompletionWrapper wrapper =
new AntElementCompletionWrapper((AntElement)element.getParent(), completionText, element.getProject(), AntElementRole.TASK_ROLE) {
public PsiElement getContext() {
return xmlTag;
}
};
return new LookupElement[] {AutoCompletionPolicy.GIVE_CHANCE_TO_OVERWRITE.applyPolicy(
LookupElementBuilder.create(wrapper, completionText))};
}
public TextRange getRangeInElement() {
return myRange;
}
}
@@ -1,74 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;
public class AntEntityReference implements PsiReference {
private final AntElement myElement;
private final PsiReference myXmlRef;
public AntEntityReference(final AntElement element, final PsiReference xmlRef) {
myElement = element;
myXmlRef = xmlRef;
}
public PsiElement getElement() {
return myElement;
}
public TextRange getRangeInElement() {
return myXmlRef.getRangeInElement();
}
@Nullable
public PsiElement resolve() {
return myXmlRef.resolve();
}
@NotNull
public String getCanonicalText() {
return myXmlRef.getCanonicalText();
}
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
return myXmlRef.handleElementRename(newElementName);
}
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
return myXmlRef.bindToElement(element);
}
public boolean isReferenceTo(PsiElement element) {
return myXmlRef.isReferenceTo(element);
}
@NotNull
public Object[] getVariants() {
return EMPTY_ARRAY;
}
public boolean isSoft() {
return myXmlRef.isSoft();
}
}
@@ -1,122 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.lang.ant.AntBundle;
import com.intellij.lang.ant.psi.AntImport;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.impl.source.resolve.reference.impl.CachingReference;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
public class AntFileReference extends FileReference implements AntReference {
public AntFileReference(final AntFileReferenceSet set, final TextRange range, final int index, final String text) {
super(set, range, index, text);
}
@Nullable
public String getText() {
final String _path = getElement().computeAttributeValue(super.getText());
if (_path == null) {
return null;
}
final String text = FileUtil.toSystemIndependentName(_path);
return text.endsWith("/")? text.substring(0, text.length() - "/".length()) : text;
}
public AntStructuredElement getElement() {
return (AntStructuredElement)super.getElement();
}
@NotNull
public AntFileReferenceSet getFileReferenceSet() {
return (AntFileReferenceSet)super.getFileReferenceSet();
}
public String getUnresolvedMessagePattern() {
return AntBundle.message("file.doesnt.exist", getCanonicalRepresentationText());
}
public boolean shouldBeSkippedByAnnotator() {
return isSoft();
}
public void setShouldBeSkippedByAnnotator(boolean value) {
}
@NotNull
public IntentionAction[] getFixes() {
return IntentionAction.EMPTY_ARRAY;
}
@Nullable
public String getCanonicalRepresentationText() {
final AntStructuredElement element = getElement();
final String value = getCanonicalText();
return element.computeAttributeValue(value);
}
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
final AntStructuredElement antElement = getElement();
final PsiElement element = getManipulatorElement();
CachingReference.getManipulator(element).handleContentChange(element, getRangeInElement().shiftRight(
antElement.getTextRange().getStartOffset() - element.getTextRange().getStartOffset()), newElementName);
return antElement;
}
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
if (!(element instanceof PsiFileSystemItem)) throw new IncorrectOperationException("Cannot bind to element");
final VirtualFile dstVFile = PsiUtilBase.getVirtualFile(element);
final AntStructuredElement se = getElement();
final PsiFile file = se.getContainingFile();
if (dstVFile == null) throw new IncorrectOperationException("Cannot bind to non-physical element:" + element);
VirtualFile currentFile = file.getVirtualFile();
if (!(se instanceof AntImport)) {
final String baseDir = se.getAntProject().getBaseDir();
if (baseDir != null && baseDir.length() > 0) {
final File f = new File(currentFile.getParent().getPath(), baseDir);
currentFile = LocalFileSystem.getInstance().findFileByPath(f.getAbsolutePath().replace(File.separatorChar, '/'));
}
}
final String newName = VfsUtil.getPath(currentFile, dstVFile, '/');
if (newName == null) {
throw new IncorrectOperationException(
"Cannot find path between files; src = " + currentFile.getPresentableUrl() + "; dst = " + dstVFile.getPresentableUrl());
}
final PsiElement me = getManipulatorElement();
TextRange range = new TextRange(getFileReferenceSet().getStartInElement(), getRangeInElement().getEndOffset());
range = range.shiftRight(se.getTextRange().getStartOffset() - me.getTextRange().getStartOffset());
return CachingReference.getManipulator(me).handleContentChange(me, range, newName);
}
private PsiElement getManipulatorElement() {
return getFileReferenceSet().getManipulatorElement();
}
}
@@ -1,122 +0,0 @@
/*
* Copyright 2000-2012 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.lang.ant.psi.impl.reference;
import com.intellij.lang.ant.psi.*;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.ManagingFS;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.PsiReferenceProvider;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
import com.intellij.psi.xml.XmlAttributeValue;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
public class AntFileReferenceSet extends FileReferenceSet {
private final XmlAttributeValue myValue;
public AntFileReferenceSet(final AntStructuredElement element, final XmlAttributeValue value, final PsiReferenceProvider provider) {
super(cutTrailingSlash(FileUtil.toSystemIndependentName(value.getValue())), element,
value.getTextRange().getStartOffset() - element.getTextRange().getStartOffset() + 1, provider, SystemInfo.isFileSystemCaseSensitive);
myValue = value;
}
private static String cutTrailingSlash(String path) {
if (path.endsWith("/")) {
return path.substring(0, path.length() - 1);
}
return path;
}
protected boolean isSoft() {
final AntStructuredElement element = getElement();
if (!(element instanceof AntImport ||
element instanceof AntTypeDef ||
element instanceof AntProperty ||
element instanceof AntAnt)) {
return true;
}
if (element instanceof AntProperty) {
return ((AntProperty)element).getFileName() != null;
}
return false;
}
public AntFileReference createFileReference(final TextRange range, final int index, final String text) {
return new AntFileReference(this, range, index, text);
}
public AntStructuredElement getElement() {
return (AntStructuredElement)super.getElement();
}
@Nullable
public String getPathString() {
return getElement().computeAttributeValue(super.getPathString());
}
public boolean isAbsolutePathReference() {
if (super.isAbsolutePathReference()) {
return true;
}
return FileUtil.isAbsolute(getPathString());
}
// todo: correct context for "output" attribute file reference of the "ant" task
@NotNull
public Collection<PsiFileSystemItem> computeDefaultContexts() {
final AntStructuredElement element = getElement();
final AntFile antFile = element.getAntFile();
if (antFile != null) {
VirtualFile vFile = antFile.getContainingPath();
if (isAbsolutePathReference()) {
if (SystemInfo.isWindows) {
vFile = ManagingFS.getInstance().findRoot("", LocalFileSystem.getInstance());
}
else {
vFile = LocalFileSystem.getInstance().findFileByPath("/");
}
}
else {
if (!(element instanceof AntImport)) {
final String basedir = element.computeAttributeValue("${basedir}");
assert basedir != null;
vFile = LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(basedir));
}
}
if (vFile != null) {
final PsiDirectory directory = antFile.getViewProvider().getManager().findDirectory(vFile);
if (directory != null) {
return Collections.<PsiFileSystemItem>singleton(directory);
}
}
}
return super.computeDefaultContexts();
}
XmlAttributeValue getManipulatorElement() {
return myValue;
}
}
@@ -1,100 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.source.resolve.reference.impl.CachingReference;
import com.intellij.psi.xml.XmlAttribute;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class AntGenericReference extends CachingReference implements AntReference {
private final AntElement myAntElement;
private final String myText;
private final TextRange myTextRange;
private final XmlAttribute myAttribute;
protected AntGenericReference(final AntElement element, final String str, final TextRange textRange, final XmlAttribute attribute) {
myAntElement = element;
myText = str;
myTextRange = textRange;
myAttribute = attribute;
}
protected AntGenericReference(final AntStructuredElement element, final XmlAttribute attr) {
myAntElement = element;
myText = (attr == null) ? element.getSourceElement().getName() : attr.getName();
int startInElement = (attr == null) ? 1 : attr.getTextRange().getStartOffset() - element.getTextRange().getStartOffset();
myTextRange = new TextRange(startInElement, myText.length() + startInElement);
myAttribute = attr;
}
protected AntGenericReference(final AntStructuredElement element) {
this(element, null);
}
public AntElement getElement() {
return myAntElement;
}
public TextRange getRangeInElement() {
return myTextRange;
}
@NotNull
public String getCanonicalText() {
return myText;
}
public boolean shouldBeSkippedByAnnotator() {
return false;
}
public void setShouldBeSkippedByAnnotator(boolean value) {}
@NotNull
public IntentionAction[] getFixes() {
return IntentionAction.EMPTY_ARRAY;
}
protected XmlAttribute getAttribute() {
return myAttribute;
}
@Nullable
public String getCanonicalRepresentationText() {
final AntElement element = getElement();
final String value = getCanonicalText();
if( element instanceof AntStructuredElement) {
return ((AntStructuredElement)element).computeAttributeValue(value);
}
return element.getAntProject().computeAttributeValue(value);
}
@Override
public PsiElement resolveInner() {
throw new UnsupportedOperationException();
}
public String getUnresolvedMessagePattern() {
return CodeInsightBundle.message("error.cannot.resolve.default.message");
}
}
@@ -1,123 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference;
import com.intellij.lang.ant.psi.AntAllTasksContainer;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntMacroDef;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.*;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.StringSetSpinAllocator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
public class AntMacroDefParameterReference extends AntGenericReference {
private final XmlElement myXmlElement;
public AntMacroDefParameterReference(final AntElement antElement,
final String str,
final TextRange textRange,
final XmlElement xmlElement) {
super(antElement, str, textRange, null);
myXmlElement = xmlElement;
}
@NotNull
public String getCanonicalText() {
String text = super.getCanonicalText();
if (text.indexOf("${") >= 0) {
final AntStructuredElement se = PsiTreeUtil.getParentOfType(getElement(), AntStructuredElement.class, true);
if (se != null) {
text = se.computeAttributeValue(text);
}
}
return text;
}
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
final AntElement element = getElement();
final String oldName = getCanonicalText();
if (oldName != null && !oldName.equals(newElementName)) {
if (myXmlElement instanceof XmlAttributeValue) {
final String text = myXmlElement.getText();
if (text.length() > 2) {
((XmlAttribute)myXmlElement.getParent())
.setValue(text.substring(1, text.length() - 1).replace("@{" + oldName + '}', "@{" + newElementName + '}'));
}
}
else {
final XmlTagValue tagValue = ((XmlTag)myXmlElement).getValue();
tagValue.setText(tagValue.getText().replace("@{" + oldName + '}', "@{" + newElementName + '}'));
}
//element.subtreeChanged();
}
return element;
}
@Nullable
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
return handleElementRename(((PsiNamedElement)element).getName());
}
public PsiElement resolveInner() {
final AntMacroDef macrodef = PsiTreeUtil.getParentOfType(getElement(), AntMacroDef.class, true);
if (macrodef != null) {
final String name = getCanonicalText();
if (name != null) {
for (final PsiElement child : macrodef.getChildren()) {
if (child instanceof AntStructuredElement && !(child instanceof AntAllTasksContainer)) {
if (name.equals(((AntStructuredElement)child).getName())) {
return child;
}
}
}
}
}
return null;
}
@NotNull
@SuppressWarnings({"HardCodedStringLiteral"})
public Object[] getVariants() {
final Set<String> variants = StringSetSpinAllocator.alloc();
try {
AntMacroDef macrodef = PsiTreeUtil.getParentOfType(getElement(), AntMacroDef.class, true);
if (macrodef != null) {
for (PsiElement child : macrodef.getChildren()) {
if (child instanceof AntStructuredElement) {
AntStructuredElement element = (AntStructuredElement)child;
if (element.getSourceElement().getName().equals("attribute")) {
variants.add(element.getName());
}
}
}
}
final int count = variants.size();
return (count == 0) ? EMPTY_ARRAY : variants.toArray(new String[count]);
}
finally {
StringSetSpinAllocator.dispose(variants);
}
}
}
@@ -1,178 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.lang.ant.AntBundle;
import com.intellij.lang.ant.AntElementRole;
import com.intellij.lang.ant.misc.PsiElementSetSpinAllocator;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntFile;
import com.intellij.lang.ant.psi.AntProject;
import com.intellij.lang.ant.psi.AntProperty;
import com.intellij.lang.ant.quickfix.AntChangeContextFix;
import com.intellij.lang.ant.quickfix.AntCreatePropertyFix;
import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.StringSetSpinAllocator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class AntPropertyReference extends AntGenericReference {
public AntPropertyReference(final AntElement antElement, final String str, final TextRange textRange, final XmlAttribute attribute) {
super(antElement, str, textRange, attribute);
}
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
final AntElement element = getElement();
final String oldName = getCanonicalText();
final XmlAttribute attr = getAttribute();
final XmlAttributeValue attrValue = attr.getValueElement();
if (attrValue != null) {
final int valueStartOffset = attrValue.getTextRange().getStartOffset() - element.getTextRange().getStartOffset() + 1;
final String value = attr.getValue();
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
final AntFile antFile = element.getAntFile();
final AntProperty resolved = antFile != null? antFile.getProperty(oldName) : null;
final String prefix = resolved != null? resolved.getPrefix() : null;
final int startOffset = getRangeInElement().getStartOffset();
final int endOffset = getRangeInElement().getEndOffset();
if (valueStartOffset < startOffset) {
builder.append(value.substring(0, startOffset - valueStartOffset));
}
if (prefix != null) {
builder.append(prefix).append(".");
}
builder.append(newElementName);
if (endOffset < valueStartOffset + value.length()) {
builder.append(value.substring(endOffset - valueStartOffset));
}
attr.setValue(builder.toString());
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
return element;
}
@Nullable
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
return handleElementRename(((PsiNamedElement)element).getName());
}
public PsiElement resolveInner() {
final AntElement elem = getElement();
final AntFile contextFile = null/*AntConfigurationBase.getInstance(elem.getProject()).getEffectiveContextFile(elem.getAntFile())*/;
if (contextFile == null) {
return null;
}
final String text = getCanonicalText();
AntProperty resolved = contextFile.getProperty(text);
if (resolved != null) {
final String propName = cutPrefix(text, resolved.getPrefix());
final PropertiesFile propFile = resolved.getPropertiesFile();
if (propFile != null) {
IProperty property = propFile.findPropertyByKey(propName);
return property == null ? null : property.getPsiElement();
}
return resolved.getFormatElement(propName);
}
return null;
}
private static String cutPrefix(final String text, final String prefix) {
if (prefix != null && text.startsWith(prefix) && prefix.length() < text.length() && text.charAt(prefix.length()) == '.') {
return text.substring(prefix.length() + 1);
}
return text;
}
public String getUnresolvedMessagePattern() {
return AntBundle.message("unknown.property", getCanonicalText());
}
@NotNull
public Object[] getVariants() {
final AntElement currentElement = getElement();
final Set<PsiElement> variants = PsiElementSetSpinAllocator.alloc();
try {
final AntFile antFile = currentElement.getAntFile();
final Project project = currentElement.getProject();
for (final AntProperty property : antFile.getProperties()) {
if (currentElement == property) {
continue;
}
final String[] names = property.getNames();
if (names != null) {
for (final String name : names) {
variants.add(new AntElementCompletionWrapper((AntElement)property.getParent(), name, project, AntElementRole.PROPERTY_ROLE));
}
}
}
return ArrayUtil.toObjectArray(variants);
}
finally {
PsiElementSetSpinAllocator.dispose(variants);
}
}
@NotNull
public IntentionAction[] getFixes() {
final String name = getCanonicalRepresentationText();
if (name == null || name.length() == 0) return IntentionAction.EMPTY_ARRAY;
final List<IntentionAction> result = new ArrayList<IntentionAction>();
final AntProject project = getElement().getAntProject();
result.add(new AntCreatePropertyFix(this));
final Set<String> files = StringSetSpinAllocator.alloc();
try {
for (final PsiElement child : project.getChildren()) {
if (child instanceof AntProperty) {
final PropertiesFile propFile = ((AntProperty)child).getPropertiesFile();
if (propFile != null) {
final String fileName = propFile.getName();
if (!files.contains(fileName)) {
files.add(fileName);
result.add(new AntCreatePropertyFix(this, propFile));
}
}
}
}
}
finally {
StringSetSpinAllocator.dispose(files);
}
result.add(new AntChangeContextFix());
return result.toArray(new IntentionAction[result.size()]);
}
}
@@ -1,134 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference;
import com.intellij.lang.ant.AntBundle;
import com.intellij.lang.ant.misc.PsiElementSetSpinAllocator;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntFile;
import com.intellij.lang.ant.psi.AntProject;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
public class AntRefIdReference extends AntGenericReference {
public AntRefIdReference(final AntElement antElement, final String str, final TextRange textRange, final XmlAttribute attribute) {
super(antElement, str, textRange, attribute);
}
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
final AntElement element = getElement();
if (element instanceof AntStructuredElement) {
getAttribute().setValue(newElementName);
}
return element;
}
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
if (element instanceof AntStructuredElement) {
final PsiNamedElement psiNamedElement = (PsiNamedElement)element;
return handleElementRename(psiNamedElement.getName());
}
throw new IncorrectOperationException("Can bind only to ant structured elements.");
}
public AntStructuredElement getElement() {
return (AntStructuredElement)super.getElement();
}
public String getUnresolvedMessagePattern() {
return AntBundle.message("cannot.resolve.refid", getCanonicalRepresentationText());
}
public PsiElement resolveInner() {
final String id = getCanonicalRepresentationText();
final Set<PsiElement> elementsDepthStack = PsiElementSetSpinAllocator.alloc();
try {
final AntStructuredElement elem = getElement();
final AntFile contextFile = null/*AntConfigurationBase.getInstance(elem.getProject()).getEffectiveContextFile(elem.getAntFile())*/;
return resolve(id, contextFile.getAntProject(), elementsDepthStack);
}
finally {
PsiElementSetSpinAllocator.dispose(elementsDepthStack);
}
}
@NotNull
public Object[] getVariants() {
final Set<PsiElement> variants = PsiElementSetSpinAllocator.alloc();
try {
final Set<PsiElement> elementsDepthStack = PsiElementSetSpinAllocator.alloc();
try {
getVariants(getElement().getAntProject(), variants, elementsDepthStack);
return ArrayUtil.toObjectArray(variants);
}
finally {
PsiElementSetSpinAllocator.dispose(elementsDepthStack);
}
}
finally {
PsiElementSetSpinAllocator.dispose(variants);
}
}
@Nullable
private static AntElement resolve(final String id, final AntProject project, final Set<PsiElement> elementsDepthStack) {
if (elementsDepthStack.contains(project)) return null;
elementsDepthStack.add(project);
try {
AntElement refId = project.getElementByRefId(id);
if (refId == null) {
for (final AntFile file : project.getImportedFiles()) {
refId = resolve(id, file.getAntProject(), elementsDepthStack);
if (refId != null) break;
}
}
return refId;
}
finally {
elementsDepthStack.remove(project);
}
}
private static void getVariants(final AntProject project, final Set<PsiElement> variants, final Set<PsiElement> elementsDepthStack) {
if (elementsDepthStack.contains(project)) return;
elementsDepthStack.add(project);
try {
for (final String id : project.getRefIds()) {
final AntElement refElement = project.getElementByRefId(id);
if (refElement != null) {
variants.add(refElement);
}
}
for (final AntFile file : project.getImportedFiles()) {
getVariants(file.getAntProject(), variants, elementsDepthStack);
}
}
finally {
elementsDepthStack.remove(project);
}
}
}
@@ -1,35 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference;
import com.intellij.codeInsight.intention.IntentionAction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface AntReference {
boolean shouldBeSkippedByAnnotator();
void setShouldBeSkippedByAnnotator(boolean value);
String getUnresolvedMessagePattern();
@NotNull
IntentionAction[] getFixes();
@Nullable
String getCanonicalRepresentationText();
}
@@ -1,72 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.impl.*;
import com.intellij.lang.ant.psi.impl.reference.providers.*;
import com.intellij.psi.PsiReferenceProvider;
import com.intellij.util.containers.HashMap;
import java.util.Map;
public class AntReferenceProvidersRegistry {
private static final Map<Class, PsiReferenceProvider[]> ourProviders;
static {
ourProviders = new HashMap<Class, PsiReferenceProvider[]>();
final AntAttributeReferenceProvider attrProvider = new AntAttributeReferenceProvider();
final AntElementNameReferenceProvider nameProvider = new AntElementNameReferenceProvider();
final AntPropertyReferenceProvider propProvider = new AntPropertyReferenceProvider();
final AntFileReferenceProvider fileProvider = new AntFileReferenceProvider();
final AntRefIdReferenceProvider refIdProvider = new AntRefIdReferenceProvider();
final AntMacroDefParameterReferenceProvider macroParamsProvider = new AntMacroDefParameterReferenceProvider();
final AntSingleTargetReferenceProvider targetProvider = new AntSingleTargetReferenceProvider();
ourProviders.put(AntProjectImpl.class, new PsiReferenceProvider[]{targetProvider, nameProvider, attrProvider});
ourProviders.put(AntTargetImpl.class, new PsiReferenceProvider[]{new AntTargetListReferenceProvider(), propProvider, refIdProvider,
nameProvider, attrProvider});
ourProviders.put(AntStructuredElementImpl.class, new PsiReferenceProvider[]{fileProvider, propProvider, refIdProvider, nameProvider,
attrProvider, macroParamsProvider});
ourProviders.put(AntTimestampFormatImpl.class, ourProviders.get(AntStructuredElementImpl.class));
ourProviders.put(AntTaskImpl.class, ourProviders.get(AntStructuredElementImpl.class));
ourProviders.put(AntPropertyImpl.class, ourProviders.get(AntStructuredElementImpl.class));
ourProviders.put(AntMacroDefImpl.class, ourProviders.get(AntStructuredElementImpl.class));
ourProviders.put(AntPresetDefImpl.class, ourProviders.get(AntStructuredElementImpl.class));
ourProviders.put(AntTypeDefImpl.class, ourProviders.get(AntStructuredElementImpl.class));
ourProviders.put(AntImportImpl.class, new PsiReferenceProvider[]{fileProvider, propProvider, nameProvider, attrProvider});
ourProviders.put(AntAntImpl.class, new PsiReferenceProvider[]{fileProvider, propProvider, nameProvider, attrProvider,
targetProvider, macroParamsProvider});
ourProviders.put(AntBuildNumberImpl.class,
new PsiReferenceProvider[]{fileProvider, propProvider, nameProvider, attrProvider, macroParamsProvider});
ourProviders.put(AntCallImpl.class, new PsiReferenceProvider[]{targetProvider, propProvider, refIdProvider, nameProvider,
attrProvider, macroParamsProvider});
ourProviders.put(AntDirSetImpl.class, ourProviders.get(AntStructuredElementImpl.class));
ourProviders.put(AntFileListImpl.class, ourProviders.get(AntStructuredElementImpl.class));
ourProviders.put(AntFileSetImpl.class, ourProviders.get(AntStructuredElementImpl.class));
ourProviders.put(AntPathImpl.class, ourProviders.get(AntStructuredElementImpl.class));
}
private AntReferenceProvidersRegistry() {
}
public static PsiReferenceProvider[] getProvidersByElement(final AntElement element) {
PsiReferenceProvider[] result = ourProviders.get(element.getClass());
return (result != null) ? result : PsiReferenceProvider.EMPTY_ARRAY;
}
}
@@ -1,222 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.lang.ant.AntBundle;
import com.intellij.lang.ant.AntSupport;
import com.intellij.lang.ant.config.AntConfigurationBase;
import com.intellij.lang.ant.psi.*;
import com.intellij.lang.ant.psi.impl.AntAntImpl;
import com.intellij.lang.ant.quickfix.AntChangeContextFix;
import com.intellij.lang.ant.quickfix.AntCreateTargetFix;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiLock;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class AntTargetReference extends AntGenericReference {
private boolean myShouldBeSkippedByAnnotator;
public AntTargetReference(final AntElement antElement, final String str, final TextRange textRange, final XmlAttribute attribute) {
super(antElement, str, textRange, attribute);
setShouldBeSkippedByAnnotator(false);
}
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
final AntElement element = getElement();
if (element instanceof AntProject || element instanceof AntCall || element instanceof AntAnt) {
getAttribute().setValue(newElementName);
}
else if (element instanceof AntTarget) {
int start = getElementStartOffset() + getReferenceStartOffset() - getAttributeValueStartOffset();
final String value = getAttribute().getValue();
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
if (start > 0) {
builder.append(value.substring(0, start));
}
builder.append(newElementName);
if (value.length() > start + getRangeInElement().getLength()) {
builder.append(value.substring(start + getRangeInElement().getLength()));
}
getAttribute().setValue(builder.toString());
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
return element;
}
@Nullable
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
if (element instanceof AntTarget) {
final PsiNamedElement psiNamedElement = (PsiNamedElement)element;
return handleElementRename(psiNamedElement.getName());
}
throw new IncorrectOperationException("Can bind only to ant targets.");
}
public PsiElement resolveInner() {
final String name = getCanonicalRepresentationText();
if (name == null) return null;
final AntElement element = getElement();
final AntConfigurationBase antConfig = AntConfigurationBase.getInstance(element.getProject());
AntTarget result = null;
if (element instanceof AntAntImpl) {
final PsiFile psiFile = ((AntAntImpl)element).getCalledAntFile();
if (psiFile != null) {
AntFile antFile = AntSupport.getAntFile(psiFile);
if (antFile != null) {
final AntFile context = null/*antConfig.getEffectiveContextFile(antFile)*/;
assert context != null;
final AntProject project = context.getAntProject();
if (project != null) {
result = resolveTargetImpl(name, project);
}
}
}
}
if (result == null) {
final AntFile context = null/*antConfig.getEffectiveContextFile(element.getAntFile())*/;
assert context != null;
result = resolveTargetImpl(name, context.getAntProject());
}
return result;
}
private static AntTarget resolveTargetImpl(final String name, final AntProject project) {
final AntTarget result = project.getTarget(name);
if (result != null) {
return result;
}
for (final AntTarget target : project.getImportedTargets()) {
if (name.equals(target.getName())) {
return target;
}
}
for (final AntTarget target : project.getImportedTargets()) {
if (name.equals(target.getQualifiedName())) {
return target;
}
}
return null;
}
public String getUnresolvedMessagePattern() {
return AntBundle.message("cannot.resolve.target", getCanonicalRepresentationText());
}
public boolean shouldBeSkippedByAnnotator() {
synchronized (PsiLock.LOCK) {
return myShouldBeSkippedByAnnotator;
}
}
public void setShouldBeSkippedByAnnotator(boolean value) {
synchronized (PsiLock.LOCK) {
myShouldBeSkippedByAnnotator = value;
}
}
@NotNull
public Object[] getVariants() {
final AntElement element = getElement();
if (element instanceof AntAntImpl) {
final PsiFile psiFile = ((AntAntImpl)element).getCalledAntFile();
if (psiFile != null) {
AntFile antFile;
if (psiFile instanceof AntFile) {
antFile = (AntFile)psiFile;
}
else {
antFile = AntSupport.getAntFile(psiFile);
}
final AntProject project = (antFile == null) ? null : antFile.getAntProject();
if (project != null) {
return project.getTargets();
}
}
}
List<AntTarget> result = new ArrayList<AntTarget>();
final AntProject project = element.getAntProject();
final AntTarget[] targets = project.getTargets();
for (final AntTarget target : targets) {
if (target != element) {
result.add(target);
}
}
ContainerUtil.addAll(result, project.getImportedTargets());
return result.toArray();
}
@NotNull
public IntentionAction[] getFixes() {
final String name = getCanonicalRepresentationText();
if (name == null || name.length() == 0) return IntentionAction.EMPTY_ARRAY;
final AntProject project = getElement().getAntProject();
final AntFile[] importedFiles = project.getImportedFiles();
final List<IntentionAction> result = new ArrayList<IntentionAction>(importedFiles.length + 1);
result.add(new AntCreateTargetFix(this));
for (final AntFile file : importedFiles) {
if (file.isPhysical()) {
result.add(new AntCreateTargetFix(this, file));
}
}
result.add(new AntChangeContextFix());
return result.toArray(new IntentionAction[result.size()]);
}
private int getElementStartOffset() {
return getElement().getTextRange().getStartOffset();
}
private int getReferenceStartOffset() {
return getRangeInElement().getStartOffset();
}
private int getAttributeValueStartOffset() {
final XmlAttribute attr = getAttribute();
final XmlAttributeValue valueElement = attr.getValueElement();
return (valueElement == null) ? attr.getTextRange().getEndOffset() + 1 : valueElement.getTextRange().getStartOffset() + 1;
}
}
@@ -1,74 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference.providers;
import com.intellij.lang.ant.misc.PsiReferenceListSpinAllocator;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.lang.ant.psi.impl.reference.AntAttributeReference;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.PsiReferenceProvider;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlToken;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class AntAttributeReferenceProvider extends PsiReferenceProvider {
@SuppressWarnings({"HardCodedStringLiteral"})
@NotNull
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull final ProcessingContext context) {
if (!(element instanceof AntStructuredElement)) {
return PsiReference.EMPTY_ARRAY;
}
final AntStructuredElement se = (AntStructuredElement)element;
final int elementStartOffset = se.getTextRange().getStartOffset();
final List<PsiReference> list = PsiReferenceListSpinAllocator.alloc();
try {
for (PsiElement child : se.getSourceElement().getChildren()) {
if (child instanceof XmlToken) {
XmlToken token = (XmlToken)child;
// TODO: move XmlTokenType to openAPI
if (token.getTokenType().toString().equals("XML_TAG_END")) {
break;
}
}
else if (child instanceof PsiWhiteSpace) {
final int off = child.getTextRange().getStartOffset() - elementStartOffset + 1;
list.add(new AntAttributeReference(se, " ", new TextRange(off, off), null));
}
else if (child instanceof XmlAttribute) {
final PsiElement nameElement = child.getFirstChild();
if (nameElement != null) {
final int off = nameElement.getTextRange().getStartOffset() - elementStartOffset;
final String text = nameElement.getText();
list.add(new AntAttributeReference(se, text, new TextRange(off, off + text.length()), null));
}
}
}
final int count = list.size();
return (count == 0) ? PsiReference.EMPTY_ARRAY : list.toArray(new PsiReference[count]);
}
finally {
PsiReferenceListSpinAllocator.dispose(list);
}
}
}
@@ -1,99 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference.providers;
import com.intellij.lang.ant.misc.PsiReferenceListSpinAllocator;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.lang.ant.psi.AntTask;
import com.intellij.lang.ant.psi.impl.reference.AntElementNameReference;
import com.intellij.lang.ant.psi.impl.reference.AntEndElementNameReference;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiReferenceProvider;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlTag;
import com.intellij.psi.xml.XmlToken;
import com.intellij.psi.xml.XmlTokenType;
import com.intellij.util.ProcessingContext;
import com.intellij.xml.util.XmlTagUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class AntElementNameReferenceProvider extends PsiReferenceProvider {
@NotNull
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull final ProcessingContext context) {
if (!(element instanceof AntStructuredElement)) {
return PsiReference.EMPTY_ARRAY;
}
final AntStructuredElement se = (AntStructuredElement)element;
final List<PsiReference> result = PsiReferenceListSpinAllocator.alloc();
try {
result.add(new AntElementNameReference(se));
if (element instanceof AntTask) {
final AntTask task = (AntTask)element;
if (task.isMacroDefined() || task.isScriptDefined()) {
final XmlAttribute[] attrs = task.getSourceElement().getAttributes();
if (attrs.length != 0) {
for (XmlAttribute attr : attrs) {
result.add(new AntElementNameReference(task, attr));
}
}
}
}
final AntElementNameReference endReference = findEndElementNameReference(se);
if (endReference != null) {
result.add(endReference);
}
return result.toArray(new PsiReference[result.size()]);
}
finally {
PsiReferenceListSpinAllocator.dispose(result);
}
}
@Nullable
private static AntEndElementNameReference findEndElementNameReference(final AntStructuredElement element) {
final XmlTag tag = element.getSourceElement();
final PsiElement endTagElement = XmlTagUtil.getEndTagNameElement(tag);
if (endTagElement == null) {
return null;
}
final TextRange elementRange = element.getTextRange();
final TextRange endTagRange = endTagElement.getTextRange();
final TextRange refRange = new TextRange(
endTagRange.getStartOffset() - elementRange.getStartOffset(),
endTagRange.getEndOffset() - elementRange.getStartOffset()
);
return new AntEndElementNameReference(element, refRange, isClosed(endTagElement));
}
private static boolean isClosed(PsiElement current) {
for (PsiElement e = current; e != null; e = e.getNextSibling()) {
if (e instanceof XmlToken) {
final IElementType tokenType = ((XmlToken)e).getTokenType();
if (tokenType == XmlTokenType.XML_TAG_END || tokenType == XmlTokenType.XML_EMPTY_ELEMENT_END) {
return true;
}
}
}
return false;
}
}
@@ -1,65 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference.providers;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.lang.ant.psi.impl.reference.AntFileReferenceSet;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiReferenceProvider;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.util.ProcessingContext;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class AntFileReferenceProvider extends PsiReferenceProvider {
@NotNull
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull final ProcessingContext context) {
AntStructuredElement antElement = (AntStructuredElement)element;
final List<String> referenceAttributes = antElement.getFileReferenceAttributes();
if (referenceAttributes.isEmpty()) {
return PsiReference.EMPTY_ARRAY;
}
final List<PsiReference> refList = new ArrayList<PsiReference>();
for (String attrib : referenceAttributes) {
final XmlAttribute attr = antElement.getSourceElement().getAttribute(attrib, null);
if (attr == null) {
continue;
}
final XmlAttributeValue xmlAttributeValue = attr.getValueElement();
if (xmlAttributeValue == null) {
continue;
}
final String attrValue = attr.getValue();
if (attrValue == null || attrValue.length() == 0 || isSingleSlash(attrValue) || attrValue.indexOf("@{") >= 0) {
continue;
}
final AntFileReferenceSet refSet = new AntFileReferenceSet(antElement, xmlAttributeValue, this);
ContainerUtil.addAll(refList, refSet.getAllReferences());
}
return refList.toArray(new PsiReference[refList.size()]);
}
private static boolean isSingleSlash(final String attrValue) {
return "/".equals(attrValue) || "\\".equals(attrValue);
}
}
@@ -1,98 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference.providers;
import com.intellij.lang.ant.misc.PsiReferenceListSpinAllocator;
import com.intellij.lang.ant.psi.AntAllTasksContainer;
import com.intellij.lang.ant.psi.AntMacroDef;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.lang.ant.psi.impl.reference.AntMacroDefParameterReference;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.ElementManipulators;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiReferenceProvider;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlElement;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class AntMacroDefParameterReferenceProvider extends PsiReferenceProvider {
@NotNull
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull final ProcessingContext context) {
if (!(element instanceof AntStructuredElement)) {
return PsiReference.EMPTY_ARRAY;
}
final AntStructuredElement antElement = (AntStructuredElement)element;
final AntAllTasksContainer sequential = PsiTreeUtil.getParentOfType(antElement, AntAllTasksContainer.class, true);
if (sequential == null) {
return PsiReference.EMPTY_ARRAY;
}
final AntMacroDef macrodef = PsiTreeUtil.getParentOfType(sequential, AntMacroDef.class, true);
if (macrodef == null) {
return PsiReference.EMPTY_ARRAY;
}
final List<PsiReference> refs = PsiReferenceListSpinAllocator.alloc();
try {
for (XmlAttribute attr : antElement.getSourceElement().getAttributes()) {
getXmlElementReferences(attr.getValueElement(), refs, antElement);
}
getXmlElementReferences(antElement.getSourceElement(), refs, antElement);
return (refs.size() > 0) ? refs.toArray(new PsiReference[refs.size()]) : PsiReference.EMPTY_ARRAY;
}
finally {
PsiReferenceListSpinAllocator.dispose(refs);
}
}
private static void getXmlElementReferences(final XmlElement element, final List<PsiReference> refs, final AntStructuredElement antElement) {
if (element == null) return;
final String text = ElementManipulators.getValueText(element);
final int offsetInPosition = ElementManipulators.getValueTextRange(element).getStartOffset() + element.getTextRange().getStartOffset() - antElement.getTextRange().getStartOffset();
int startIndex;
int endIndex = -1;
while ((startIndex = text.indexOf("@{", endIndex + 1)) > endIndex) {
startIndex += 2;
endIndex = startIndex;
int nestedBrackets = 0;
while (text.length() > endIndex) {
final char ch = text.charAt(endIndex);
if (ch == '}') {
if (nestedBrackets == 0) {
break;
}
--nestedBrackets;
}
else if (ch == '{') {
++nestedBrackets;
}
++endIndex;
}
if(nestedBrackets > 0 || endIndex == text.length()) return;
if (endIndex >= startIndex) {
final String name = text.substring(startIndex, endIndex);
refs.add(new AntMacroDefParameterReference(antElement, name,
new TextRange(offsetInPosition + startIndex, offsetInPosition + endIndex), element));
}
endIndex = startIndex;
}
}
}
@@ -1,155 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference.providers;
import com.intellij.lang.ant.AntBundle;
import com.intellij.lang.ant.misc.PsiReferenceListSpinAllocator;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.AntFile;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.lang.ant.psi.impl.AntFileImpl;
import com.intellij.lang.ant.psi.impl.reference.AntPropertyReference;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiReferenceProvider;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class AntPropertyReferenceProvider extends PsiReferenceProvider {
@NotNull
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull final ProcessingContext context) {
final AntStructuredElement antElement = (AntStructuredElement)element;
final XmlTag sourceElement = antElement.getSourceElement();
final XmlAttribute[] attributes = sourceElement.getAttributes();
if (attributes.length > 0) {
final List<PsiReference> refs = PsiReferenceListSpinAllocator.alloc();
try {
//final boolean isTarget = antElement instanceof AntTarget;
final boolean isSet = "isset".equals(sourceElement.getName());
for (final XmlAttribute attr : attributes) {
@NonNls final String attName = attr.getName();
if (/*isTarget && */(AntFileImpl.IF_ATTR.equals(attName) || AntFileImpl.UNLESS_ATTR.equals(attName))) {
getAttributeReference(antElement, attr, refs);
}
else if (isSet && AntFileImpl.PROPERTY.equals(attName)) {
getAttributeReference(antElement, attr, refs);
}
else {
getAttributeReferences(antElement, attr, refs);
}
}
if (refs.size() > 0) {
return refs.toArray(new PsiReference[refs.size()]);
}
}
finally {
PsiReferenceListSpinAllocator.dispose(refs);
}
}
return PsiReference.EMPTY_ARRAY;
}
/**
* Gets all references to the ${} properties.
*
* @param element
* @param attr
* @param refs
*/
private static void getAttributeReferences(final AntElement element, final XmlAttribute attr, final List<PsiReference> refs) {
final AntFile antFile = element.getAntFile();
final String value = attr.getValue();
final XmlAttributeValue xmlAttributeValue = attr.getValueElement();
if (xmlAttributeValue != null && value.indexOf("@{") < 0) {
final int offsetInPosition = xmlAttributeValue.getTextRange().getStartOffset() - element.getTextRange().getStartOffset() + 1;
int startIndex;
int endIndex = -1;
while ((startIndex = value.indexOf("${", endIndex + 1)) > endIndex) {
if (startIndex > 0 && value.charAt(startIndex - 1) == '$') {
// the '$' is escaped
endIndex = startIndex + 1;
continue;
}
startIndex += 2;
endIndex = startIndex;
int nestedBrackets = 0;
while (value.length() > endIndex) {
final char ch = value.charAt(endIndex);
if (ch == '}') {
if (nestedBrackets == 0) {
break;
}
--nestedBrackets;
}
else if (ch == '{') {
++nestedBrackets;
}
++endIndex;
}
if (nestedBrackets > 0 || endIndex > value.length()) return;
if (endIndex >= startIndex) {
final String propName = value.substring(startIndex, endIndex);
if (antFile.isEnvironmentProperty(propName) && antFile.getProperty(propName) == null) {
continue;
}
refs.add(new AntPropertyReference(element, propName,
new TextRange(offsetInPosition + startIndex, offsetInPosition + endIndex), attr));
}
endIndex = startIndex;
}
}
}
/**
* Gets single reference on a property named as the attribute's and if the property is resolved.
*
* @param element
* @param attr
* @param refs
*/
private static void getAttributeReference(final AntElement element, final XmlAttribute attr, final List<PsiReference> refs) {
final AntFile antFile = element.getAntFile();
final String value = attr.getValue();
if (value == null) {
return;
}
if (antFile.isEnvironmentProperty(value) && antFile.getProperty(value) == null) {
return;
}
final XmlAttributeValue xmlAttributeValue = attr.getValueElement();
if (xmlAttributeValue != null) {
final int offsetInPosition = xmlAttributeValue.getTextRange().getStartOffset() - element.getTextRange().getStartOffset() + 1;
refs.add(new AntPropertyReference(element, value, new TextRange(offsetInPosition, offsetInPosition + value.length()), attr) {
public boolean shouldBeSkippedByAnnotator() {
return getCanonicalText().length() > 0;
}
public String getUnresolvedMessagePattern() {
return AntBundle.message("please.specify.a.property");
}
});
}
}
}
@@ -1,70 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference.providers;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.lang.ant.psi.impl.reference.AntRefIdReference;
import com.intellij.lang.ant.psi.introspection.AntAttributeType;
import com.intellij.lang.ant.psi.introspection.AntTypeDefinition;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiReferenceProvider;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.NonNls;
import java.util.ArrayList;
import java.util.List;
public class AntRefIdReferenceProvider extends PsiReferenceProvider {
@NotNull
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull final ProcessingContext context) {
if (!(element instanceof AntStructuredElement)) {
return PsiReference.EMPTY_ARRAY;
}
final AntStructuredElement se = (AntStructuredElement)element;
final List<PsiReference> refs = new ArrayList<PsiReference>();
for (XmlAttribute attr : se.getSourceElement().getAttributes()) {
if (!isRefAttribute(se, attr.getName())) {
continue;
}
final XmlAttributeValue valueElement = attr.getValueElement();
if (valueElement == null) {
continue;
}
final int offsetInPosition = valueElement.getTextRange().getStartOffset() - se.getTextRange().getStartOffset() + 1;
final String attrValue = attr.getValue();
if (attrValue == null || attrValue.indexOf("@{") >= 0) {
continue;
}
refs.add(new AntRefIdReference(se, attrValue, new TextRange(offsetInPosition, offsetInPosition + attrValue.length()), attr));
}
return refs.toArray(new PsiReference[refs.size()]);
}
private static boolean isRefAttribute(AntStructuredElement element, @NonNls final String attribName) {
if ("refid".equals(attribName)) {
return true;
}
final AntTypeDefinition typeDef = element.getTypeDefinition();
return typeDef != null && AntAttributeType.ID_REFERENCE == typeDef.getAttributeType(attribName);
}
}
@@ -1,69 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference.providers;
import com.intellij.lang.ant.psi.AntElement;
import com.intellij.lang.ant.psi.impl.AntAntImpl;
import com.intellij.lang.ant.psi.impl.AntCallImpl;
import com.intellij.lang.ant.psi.impl.AntProjectImpl;
import com.intellij.lang.ant.psi.impl.reference.AntTargetReference;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiReferenceProvider;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.containers.HashMap;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
public class AntSingleTargetReferenceProvider extends PsiReferenceProvider {
@NonNls private static final Map<Class,String> ourTypesToAttributeNames;
static {
ourTypesToAttributeNames = new HashMap<Class, String>();
ourTypesToAttributeNames.put(AntProjectImpl.class, "default");
ourTypesToAttributeNames.put(AntCallImpl.class, "target");
ourTypesToAttributeNames.put(AntAntImpl.class, "target");
}
@NotNull
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull final ProcessingContext context) {
String attributeName = ourTypesToAttributeNames.get(element.getClass());
if( attributeName == null) {
return PsiReference.EMPTY_ARRAY;
}
AntElement antElement = (AntElement)element;
final XmlAttribute attr = ((XmlTag)antElement.getSourceElement()).getAttribute(attributeName, null);
if (attr == null) {
return PsiReference.EMPTY_ARRAY;
}
final XmlAttributeValue valueElement = attr.getValueElement();
if( valueElement == null ) {
return PsiReference.EMPTY_ARRAY;
}
final int offsetInPosition = valueElement.getTextRange().getStartOffset() - antElement.getTextRange().getStartOffset() + 1;
final String attrValue = valueElement.getValue();
return new PsiReference[]{
new AntTargetReference(antElement, attrValue, new TextRange(offsetInPosition, offsetInPosition + attrValue.length()), attr)};
}
}
@@ -1,85 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.impl.reference.providers;
import com.intellij.lang.ant.misc.PsiReferenceListSpinAllocator;
import com.intellij.lang.ant.psi.AntTarget;
import com.intellij.lang.ant.psi.impl.reference.AntTargetReference;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiReferenceProvider;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class AntTargetListReferenceProvider extends PsiReferenceProvider {
@NotNull
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull final ProcessingContext context) {
final AntTarget target = (AntTarget)element;
final XmlAttribute attr = target.getSourceElement().getAttribute("depends", null);
if (attr == null) {
return PsiReference.EMPTY_ARRAY;
}
final XmlAttributeValue xmlAttributeValue = attr.getValueElement();
if (xmlAttributeValue == null) {
return PsiReference.EMPTY_ARRAY;
}
int offsetInPosition = xmlAttributeValue.getTextRange().getStartOffset() - target.getTextRange().getStartOffset() + 1;
final String value = attr.getValue();
final List<PsiReference> result = PsiReferenceListSpinAllocator.alloc();
try {
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
int i = 0;
int rightBound;
final int valueLen = value.length();
do {
rightBound = (i < valueLen) ? value.indexOf(',', i) : valueLen;
if (rightBound < 0) rightBound = valueLen;
builder.setLength(0);
int j = i;
for (; j < rightBound; ++j) {
builder.append(value.charAt(j));
}
j = 0;
final int len = builder.length();
for (; j < len; ++j) {
if (!Character.isWhitespace(builder.charAt(j))) break;
}
final String targetName = (len == 0 || j == len) ? "" : builder.substring(j);
result.add(new AntTargetReference(target, targetName,
new TextRange(offsetInPosition + i + j, offsetInPosition + i + j + targetName.length()), attr));
i = rightBound + 1;
}
while (rightBound < valueLen);
return (result.size() > 0) ? result.toArray(new PsiReference[result.size()]) : PsiReference.EMPTY_ARRAY;
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
finally {
PsiReferenceListSpinAllocator.dispose(result);
}
}
}
@@ -1,60 +0,0 @@
/*
* Copyright 2000-2009 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.lang.ant.psi.introspection;
import org.apache.tools.ant.types.Reference;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
public enum AntAttributeType {
INTEGER,
BOOLEAN,
STRING,
FILE,
ID_REFERENCE;
private static final Map<Class<?>, AntAttributeType> ourClassesMap = new HashMap<Class<?>, AntAttributeType>();
static {
ourClassesMap.put(int.class, INTEGER);
ourClassesMap.put(boolean.class, BOOLEAN);
ourClassesMap.put(File.class, FILE);
}
public static AntAttributeType create(Class antDeclaredClass) {
final AntAttributeType type = ourClassesMap.get(antDeclaredClass);
if (type != null) {
return type;
}
if (isAssignableFrom(Reference.class, antDeclaredClass)) {
return ID_REFERENCE;
}
return STRING; // default attribute type
}
private static boolean isAssignableFrom(Class interfaceClass, Class antDeclaredClass) {
final ClassLoader loader = antDeclaredClass.getClassLoader();
try {
final Class ifaceClass = loader != null? loader.loadClass(interfaceClass.getName()) : interfaceClass;
return ifaceClass.isAssignableFrom(antDeclaredClass);
}
catch (ClassNotFoundException ignored) {
}
return false;
}
}

Some files were not shown because too many files have changed in this diff Show More