mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
remove unused code and restore 'change context' fix for unresolved ant tags
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+1
-1
@@ -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;
|
||||
+2
-2
@@ -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();
|
||||
}
|
||||
+2
-2
@@ -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;
|
||||
}
|
||||
}
|
||||
-83
@@ -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");
|
||||
}
|
||||
}
|
||||
-182
@@ -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()));
|
||||
}
|
||||
}
|
||||
-62
@@ -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");
|
||||
}
|
||||
}
|
||||
-123
@@ -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();
|
||||
}
|
||||
-72
@@ -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;
|
||||
}
|
||||
}
|
||||
-74
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-99
@@ -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;
|
||||
}
|
||||
}
|
||||
-65
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
-98
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-155
@@ -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");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-70
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
-69
@@ -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)};
|
||||
}
|
||||
|
||||
}
|
||||
-85
@@ -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
Reference in New Issue
Block a user