mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git@git.labs.intellij.net:idea/community
This commit is contained in:
+6
-4
@@ -59,7 +59,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
|
||||
|
||||
protected boolean isAvailableImpl(int offset) {
|
||||
final PsiMethodCallExpression call = getMethodCall();
|
||||
if (call == null) return false;
|
||||
if (call == null || !call.isValid()) return false;
|
||||
PsiReferenceExpression ref = call.getMethodExpression();
|
||||
String name = ref.getReferenceName();
|
||||
|
||||
@@ -90,8 +90,8 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
|
||||
|
||||
PsiExpressionList argumentList = call.getArgumentList();
|
||||
List<HighlightInfo> errorsInArgList = DaemonCodeAnalyzerImpl.getHighlights(document, HighlightSeverity.ERROR, project,
|
||||
//strictly inside arg list
|
||||
argumentList.getTextRange().getStartOffset()+1,
|
||||
//strictly inside arg list
|
||||
argumentList.getTextRange().getStartOffset()+1,
|
||||
argumentList.getTextRange().getEndOffset()-1);
|
||||
return !errorsInArgList.isEmpty();
|
||||
}
|
||||
@@ -117,7 +117,6 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
|
||||
}
|
||||
|
||||
protected void invokeImpl(final PsiClass targetClass) {
|
||||
|
||||
if (targetClass == null) return;
|
||||
PsiMethodCallExpression expression = getMethodCall();
|
||||
if (expression == null) return;
|
||||
@@ -170,6 +169,9 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
|
||||
|
||||
setupVisibility(parentClass, targetClass, method.getModifierList());
|
||||
|
||||
expression = getMethodCall();
|
||||
LOG.assertTrue(expression.isValid());
|
||||
|
||||
if (shouldCreateStaticMember(expression.getMethodExpression(), targetClass) && !shouldBeAbstract(targetClass)) {
|
||||
PsiUtil.setModifierProperty(method, PsiModifier.STATIC, true);
|
||||
}
|
||||
|
||||
@@ -98,7 +98,12 @@ public class JavaResolveCache {
|
||||
type = ConcurrencyUtil.cacheOrGet(myCalculatedTypes, expr, type);
|
||||
}
|
||||
if (!type.isValid()) {
|
||||
LOG.error("Type is invalid: " + type+"; expr: '"+expr+"' is "+(expr.isValid() ? "valid":"invalid"));
|
||||
if (expr.isValid()) {
|
||||
LOG.error("Type is invalid: " + type + "; expr: '" + expr + "' is valid");
|
||||
}
|
||||
else {
|
||||
LOG.error("Expression: '"+expr+"' is invalid, must not be used for getType()");
|
||||
}
|
||||
}
|
||||
return type == NULL_TYPE ? null : type;
|
||||
}
|
||||
|
||||
@@ -179,6 +179,10 @@ public class ProblemsHolder {
|
||||
return myOnTheFly;
|
||||
}
|
||||
|
||||
public PsiFile getFile() {
|
||||
return myFile;
|
||||
}
|
||||
|
||||
public final Project getProject() {
|
||||
return myManager.getProject();
|
||||
}
|
||||
|
||||
@@ -18,6 +18,9 @@ package com.intellij.psi;
|
||||
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Trivial implementation of {@link ResolveResult}.
|
||||
@@ -67,4 +70,15 @@ public class PsiElementResolveResult implements ResolveResult{
|
||||
public String toString() {
|
||||
return "PsiElementResolveResult: " + (myElement instanceof PsiNamedElement ? ((PsiNamedElement)myElement).getName() : myElement.getText());
|
||||
}
|
||||
|
||||
public static ResolveResult[] createResults(@Nullable Collection<? extends PsiElement> elements) {
|
||||
if (elements == null || elements.isEmpty()) return EMPTY_ARRAY;
|
||||
|
||||
final ResolveResult[] results = new ResolveResult[elements.size()];
|
||||
int i = 0;
|
||||
for (PsiElement element : elements) {
|
||||
results[i++] = new PsiElementResolveResult(element);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,4 +41,15 @@ public abstract class PsiPolyVariantReferenceBase<T extends PsiElement> extends
|
||||
ResolveResult[] resolveResults = multiResolve(false);
|
||||
return resolveResults.length == 1 ? resolveResults[0].getElement() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReferenceTo(PsiElement element) {
|
||||
final ResolveResult[] results = multiResolve(false);
|
||||
for (ResolveResult result : results) {
|
||||
if (getElement().getManager().areElementsEquivalent(result.getElement(), element)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
public abstract class WalkingState<T> {
|
||||
public class WalkingState<T> {
|
||||
public interface TreeGuide<T> {
|
||||
T getNextSibling(@NotNull T element);
|
||||
T getPrevSibling(@NotNull T element);
|
||||
@@ -33,9 +33,9 @@ public abstract class WalkingState<T> {
|
||||
private final TreeGuide<T> myWalker;
|
||||
private boolean stopped;
|
||||
|
||||
public abstract void elementFinished(@NotNull T element);
|
||||
public void elementFinished(@NotNull T element) {}
|
||||
|
||||
protected WalkingState(@NotNull TreeGuide<T> delegate) {
|
||||
public WalkingState(@NotNull TreeGuide<T> delegate) {
|
||||
myWalker = delegate;
|
||||
}
|
||||
|
||||
@@ -100,4 +100,4 @@ public abstract class WalkingState<T> {
|
||||
public void stopWalking() {
|
||||
stopped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,8 +41,8 @@ public class DaemonTooltipUtil {
|
||||
public static void showInfoTooltip(@NotNull final HighlightInfo info, final Editor editor, final int defaultOffset, final int currentWidth) {
|
||||
if (info.toolTip == null) return;
|
||||
Rectangle visibleArea = editor.getScrollingModel().getVisibleArea();
|
||||
int endOffset = info.highlighter.getEndOffset();
|
||||
int startOffset = info.highlighter.getStartOffset();
|
||||
int startOffset = info.getActualStartOffset();
|
||||
int endOffset = info.getActualEndOffset();
|
||||
|
||||
Point top = editor.logicalPositionToXY(editor.offsetToLogicalPosition(startOffset));
|
||||
Point bottom = editor.logicalPositionToXY(editor.offsetToLogicalPosition(endOffset));
|
||||
|
||||
+3
-10
@@ -21,8 +21,6 @@ import com.intellij.openapi.editor.ex.ErrorStripeEvent;
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter;
|
||||
import com.intellij.openapi.project.Project;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ErrorStripeHandler extends ErrorStripeAdapter {
|
||||
private final Project myProject;
|
||||
|
||||
@@ -39,14 +37,9 @@ public class ErrorStripeHandler extends ErrorStripeAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
private HighlightInfo findInfo(RangeHighlighter highlighter) {
|
||||
List<HighlightInfo> highlights = DaemonCodeAnalyzerImpl.getHighlights(highlighter.getDocument(), myProject);
|
||||
if (highlights == null) return null;
|
||||
for (HighlightInfo info : highlights) {
|
||||
if (info.highlighter == highlighter) {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
private static HighlightInfo findInfo(final RangeHighlighter highlighter) {
|
||||
Object o = highlighter.getErrorStripeTooltip();
|
||||
if (o instanceof HighlightInfo) return (HighlightInfo)o;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -22,12 +22,12 @@ import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory;
|
||||
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar;
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.ex.InspectionProfileWrapper;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.components.AbstractProjectComponent;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.profile.Profile;
|
||||
import com.intellij.profile.ProfileChangeAdapter;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
@@ -106,4 +106,4 @@ public class WholeFileLocalInspectionsPassFactory extends AbstractProjectCompone
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -58,12 +58,10 @@ public class DefaultHighlightVisitor implements HighlightVisitor, DumbAware {
|
||||
public static final ExtensionPointName<HighlightErrorFilter> FILTER_EP_NAME = ExtensionPointName.create("com.intellij.highlightErrorFilter");
|
||||
private final HighlightErrorFilter[] myErrorFilters;
|
||||
private final Project myProject;
|
||||
private final boolean myDumb;
|
||||
|
||||
public DefaultHighlightVisitor(Project project) {
|
||||
myProject = project;
|
||||
myErrorFilters = Extensions.getExtensions(FILTER_EP_NAME, project);
|
||||
myDumb = DumbService.getInstance(myProject).isDumb();
|
||||
}
|
||||
|
||||
public boolean suitableForFile(final PsiFile file) {
|
||||
@@ -122,10 +120,11 @@ public class DefaultHighlightVisitor implements HighlightVisitor, DumbAware {
|
||||
private void runAnnotators(final PsiElement element, HighlightInfoHolder holder, final AnnotationHolderImpl annotationHolder) {
|
||||
List<Annotator> annotators = cachedAnnotators.get(element.getLanguage());
|
||||
if (annotators.isEmpty()) return;
|
||||
final boolean dumb = DumbService.getInstance(myProject).isDumb();
|
||||
|
||||
JobUtil.invokeConcurrentlyUnderMyProgress(annotators, new Processor<Annotator>() {
|
||||
public boolean process(Annotator annotator) {
|
||||
if (myDumb && !(annotator instanceof DumbAware)) {
|
||||
if (dumb && !(annotator instanceof DumbAware)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -520,29 +520,28 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec
|
||||
public void documentChanged(DocumentEvent event) {
|
||||
final Document document = event.getDocument();
|
||||
final FileViewProvider viewProvider = getCachedViewProvider(document);
|
||||
if (viewProvider != null) {
|
||||
if (viewProvider.getVirtualFile().getFileType().isBinary()) return;
|
||||
if (viewProvider == null) return;
|
||||
if (viewProvider.getVirtualFile().getFileType().isBinary()) return;
|
||||
|
||||
final List<PsiFile> files = viewProvider.getAllFiles();
|
||||
boolean commitNecessary = false;
|
||||
for (PsiFile file : files) {
|
||||
if (file == null || file instanceof PsiFileImpl && ((PsiFileImpl)file).getTreeElement() == null) continue;
|
||||
final TextBlock textBlock = getTextBlock(document, file);
|
||||
if (textBlock.isLocked()) continue;
|
||||
final List<PsiFile> files = viewProvider.getAllFiles();
|
||||
boolean commitNecessary = false;
|
||||
for (PsiFile file : files) {
|
||||
if (file == null || file instanceof PsiFileImpl && ((PsiFileImpl)file).getTreeElement() == null) continue;
|
||||
final TextBlock textBlock = getTextBlock(document, file);
|
||||
if (textBlock.isLocked()) continue;
|
||||
|
||||
if (mySmartPointerManager != null) { // mock tests
|
||||
SmartPointerManagerImpl.unfastenBelts(file);
|
||||
}
|
||||
|
||||
textBlock.documentChanged(event);
|
||||
assert file instanceof PsiFileImpl : event + "; file="+file+"; allFiles="+files+"; viewProvider="+viewProvider;
|
||||
myUncommittedDocuments.add(document);
|
||||
commitNecessary = true;
|
||||
if (mySmartPointerManager != null) { // mock tests
|
||||
SmartPointerManagerImpl.unfastenBelts(file);
|
||||
}
|
||||
|
||||
if (commitNecessary && ApplicationManager.getApplication().getCurrentWriteAction(ExternalChangeAction.class) != null){
|
||||
commitDocument(document);
|
||||
}
|
||||
textBlock.documentChanged(event);
|
||||
assert file instanceof PsiFileImpl : event + "; file="+file+"; allFiles="+files+"; viewProvider="+viewProvider;
|
||||
myUncommittedDocuments.add(document);
|
||||
commitNecessary = true;
|
||||
}
|
||||
|
||||
if (commitNecessary && ApplicationManager.getApplication().getCurrentWriteAction(ExternalChangeAction.class) != null){
|
||||
commitDocument(document);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -253,6 +253,11 @@ public class UndoManagerImpl extends UndoManager implements ProjectComponent, Ap
|
||||
clearUndoRedoQueue(DocumentReferenceManager.getInstance().create(file));
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public void clearUndoRedoQueueInTests(Document document) {
|
||||
clearUndoRedoQueue(DocumentReferenceManager.getInstance().create(document));
|
||||
}
|
||||
|
||||
protected void compact() {
|
||||
if (myCurrentOperationState == NONE && myCommandTimestamp % COMMAND_TO_RUN_COMPACT == 0) {
|
||||
doCompact();
|
||||
|
||||
@@ -70,7 +70,7 @@ public class FoldRegionImpl extends RangeMarkerImpl implements FoldRegion {
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return super.isValid() && getStartOffset() + 1 < getEndOffset();
|
||||
return super.isValid() && myStart + 1 < myEnd;
|
||||
}
|
||||
|
||||
public void setExpandedInternal(boolean toExpand) {
|
||||
|
||||
+8
-10
@@ -30,16 +30,14 @@ public class ReadWriteAccessUsageInfo2UsageAdapter extends UsageInfo2UsageAdapte
|
||||
super(usageInfo);
|
||||
myAccessedForReading = accessedForReading;
|
||||
myAccessedForWriting = accessedForWriting;
|
||||
if (myIcon == null) {
|
||||
if (myAccessedForReading && myAccessedForWriting) {
|
||||
myIcon = Icons.VARIABLE_RW_ACCESS;
|
||||
}
|
||||
else if (myAccessedForWriting) {
|
||||
myIcon = Icons.VARIABLE_WRITE_ACCESS; // If icon is changed, don't forget to change UTCompositeUsageNode.getIcon();
|
||||
}
|
||||
else if (myAccessedForReading){
|
||||
myIcon = Icons.VARIABLE_READ_ACCESS; // If icon is changed, don't forget to change UTCompositeUsageNode.getIcon();
|
||||
}
|
||||
if (myAccessedForReading && myAccessedForWriting) {
|
||||
myIcon = Icons.VARIABLE_RW_ACCESS;
|
||||
}
|
||||
else if (myAccessedForWriting) {
|
||||
myIcon = Icons.VARIABLE_WRITE_ACCESS; // If icon is changed, don't forget to change UTCompositeUsageNode.getIcon();
|
||||
}
|
||||
else if (myAccessedForReading){
|
||||
myIcon = Icons.VARIABLE_READ_ACCESS; // If icon is changed, don't forget to change UTCompositeUsageNode.getIcon();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-14
@@ -21,8 +21,6 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.ex.DocumentEx;
|
||||
import com.intellij.openapi.editor.impl.PersistentRangeMarker;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
@@ -58,7 +56,10 @@ import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.NameValidator;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author ilyas
|
||||
@@ -85,10 +86,10 @@ public class GroovyMethodInliner implements InlineHandler.Inliner {
|
||||
Map<PsiElement, String> conflicts = new HashMap<PsiElement, String>();
|
||||
|
||||
for (GroovyInlineMethodUtil.ReferenceExpressionInfo info : infos) {
|
||||
if (!(PsiUtil.isAccessible(call, info.declaration))) {
|
||||
if (!PsiUtil.isAccessible(call, info.declaration)) {
|
||||
if (info.declaration instanceof PsiMethod) {
|
||||
String className = info.containingClass.getName();
|
||||
String signature = GroovyRefactoringUtil.getMethodSignature(((PsiMethod) info.declaration));
|
||||
String signature = GroovyRefactoringUtil.getMethodSignature((PsiMethod) info.declaration);
|
||||
String name = CommonRefactoringUtil.htmlEmphasize(className + "." + signature);
|
||||
conflicts.put(info.declaration, GroovyRefactoringBundle.message("method.is.not.accessible.form.context.0", name));
|
||||
} else if (info.declaration instanceof PsiField) {
|
||||
@@ -147,9 +148,9 @@ public class GroovyMethodInliner implements InlineHandler.Inliner {
|
||||
qualifier = ((GrParenthesizedExpression) qualifier).getOperand();
|
||||
}
|
||||
qualifierDeclaration = factory.createVariableDeclaration(ArrayUtil.EMPTY_STRING_ARRAY, qualifier, null, qualName);
|
||||
innerQualifier = ((GrReferenceExpression) factory.createExpressionFromText(qualName));
|
||||
innerQualifier = (GrReferenceExpression) factory.createExpressionFromText(qualName);
|
||||
} else {
|
||||
innerQualifier = ((GrReferenceExpression) qualifier);
|
||||
innerQualifier = (GrReferenceExpression) qualifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,7 +160,7 @@ public class GroovyMethodInliner implements InlineHandler.Inliner {
|
||||
if (result != null) {
|
||||
GrExpression expression = call.replaceWithExpression(result, false);
|
||||
TextRange range = expression.getTextRange();
|
||||
return editor != null ? new PersistentRangeMarker((DocumentEx)editor.getDocument(), range.getStartOffset(), range.getEndOffset()) : null;
|
||||
return editor != null ? editor.getDocument().createRangeMarker(range.getStartOffset(), range.getEndOffset(), true) : null;
|
||||
}
|
||||
|
||||
String resultName = InlineMethodConflictSolver.suggestNewName("result", newMethod, call);
|
||||
@@ -245,13 +246,13 @@ public class GroovyMethodInliner implements InlineHandler.Inliner {
|
||||
assert replaced != null;
|
||||
|
||||
TextRange range = replaced.getTextRange();
|
||||
RangeMarker marker = editor != null ? new PersistentRangeMarker((DocumentEx)editor.getDocument(), range.getStartOffset(), range.getEndOffset()) : null;
|
||||
RangeMarker marker = editor != null ? editor.getDocument().createRangeMarker(range.getStartOffset(), range.getEndOffset(), true) : null;
|
||||
reformatOwner(owner);
|
||||
return marker;
|
||||
} else {
|
||||
GrStatement stmt;
|
||||
if (isTailMethodCall && enclosingExpr.getParent() instanceof GrReturnStatement) {
|
||||
stmt = ((GrReturnStatement) enclosingExpr.getParent());
|
||||
stmt = (GrReturnStatement) enclosingExpr.getParent();
|
||||
} else {
|
||||
stmt = enclosingExpr;
|
||||
}
|
||||
@@ -332,7 +333,7 @@ public class GroovyMethodInliner implements InlineHandler.Inliner {
|
||||
if (statement instanceof GrReturnStatement) {
|
||||
expr = ((GrReturnStatement) statement).getReturnValue();
|
||||
} else {
|
||||
expr = ((GrExpression) statement);
|
||||
expr = (GrExpression) statement;
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
@@ -382,7 +383,7 @@ public class GroovyMethodInliner implements InlineHandler.Inliner {
|
||||
if (element == null) return;
|
||||
for (PsiElement child : element.getChildren()) {
|
||||
if (child instanceof GrVariable && !(child instanceof GrParameter)) {
|
||||
defintions.add(((GrVariable) child));
|
||||
defintions.add((GrVariable) child);
|
||||
}
|
||||
if (!(child instanceof GrClosableBlock)) {
|
||||
collectInnerDefinitions(child, defintions);
|
||||
@@ -401,10 +402,10 @@ public class GroovyMethodInliner implements InlineHandler.Inliner {
|
||||
assert body != null;
|
||||
GrStatement[] statements = body.getStatements();
|
||||
if (statements.length == 1) {
|
||||
if (statements[0] instanceof GrExpression) return ((GrExpression) statements[0]);
|
||||
if (statements[0] instanceof GrExpression) return (GrExpression) statements[0];
|
||||
if (statements[0] instanceof GrReturnStatement) {
|
||||
GrExpression value = ((GrReturnStatement) statements[0]).getReturnValue();
|
||||
if (value == null && (PsiUtil.getSmartReturnType(method) != PsiType.VOID)) {
|
||||
if (value == null && PsiUtil.getSmartReturnType(method) != PsiType.VOID) {
|
||||
return GroovyPsiElementFactory.getInstance(method.getProject()).createExpressionFromText("null");
|
||||
}
|
||||
return value;
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.execution.configurations.ConfigurationPerRunnerSettings;
|
||||
import com.intellij.execution.configurations.RunnerSettings;
|
||||
import com.intellij.execution.configurations.RuntimeConfigurationException;
|
||||
import com.intellij.execution.configurations.RuntimeConfigurationWarning;
|
||||
import com.intellij.execution.runners.ProgramRunner;
|
||||
import com.intellij.execution.testframework.SourceScope;
|
||||
import com.intellij.execution.testframework.TestSearchScope;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -49,6 +50,8 @@ import java.net.Socket;
|
||||
import java.util.Collection;
|
||||
|
||||
public class TestPackage extends TestObject {
|
||||
private static BackgroundableProcessIndicator mySearchForTestsIndicator;
|
||||
|
||||
public TestPackage(final Project project,
|
||||
final JUnitConfiguration configuration,
|
||||
RunnerSettings runnerSettings,
|
||||
@@ -62,6 +65,19 @@ public class TestPackage extends TestObject {
|
||||
return data.getScope().getSourceScope(myConfiguration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult execute(Executor executor, @NotNull ProgramRunner runner) throws ExecutionException {
|
||||
try {
|
||||
return super.execute(executor, runner);
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
if (mySearchForTestsIndicator != null && !mySearchForTestsIndicator.isCanceled()) {
|
||||
mySearchForTestsIndicator.cancel(); //ensure that search for tests stops anyway
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
protected void initialize() throws ExecutionException {
|
||||
super.initialize();
|
||||
final Project project = myConfiguration.getProject();
|
||||
@@ -244,7 +260,7 @@ public class TestPackage extends TestObject {
|
||||
}
|
||||
}
|
||||
};
|
||||
ProgressManagerImpl.runProcessWithProgressAsynchronously(task, new BackgroundableProcessIndicator(task) {
|
||||
mySearchForTestsIndicator = new BackgroundableProcessIndicator(task) {
|
||||
@Override
|
||||
public void cancel() {
|
||||
try {//ensure that serverSocket.accept was interrupted
|
||||
@@ -257,7 +273,8 @@ public class TestPackage extends TestObject {
|
||||
}
|
||||
super.cancel();
|
||||
}
|
||||
});
|
||||
};
|
||||
ProgressManagerImpl.runProcessWithProgressAsynchronously(task, mySearchForTestsIndicator);
|
||||
}
|
||||
|
||||
private static boolean isSyncSearch() {
|
||||
|
||||
+36
-5
@@ -41,7 +41,8 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.module.LanguageLevelUtil;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator;
|
||||
import com.intellij.openapi.progress.impl.ProgressManagerImpl;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.ex.JavaSdkUtil;
|
||||
@@ -59,7 +60,10 @@ import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.net.NetUtils;
|
||||
import com.theoryinpractice.testng.model.*;
|
||||
import com.theoryinpractice.testng.model.IDEARemoteTestRunnerClient;
|
||||
import com.theoryinpractice.testng.model.TestData;
|
||||
import com.theoryinpractice.testng.model.TestNGRemoteListener;
|
||||
import com.theoryinpractice.testng.model.TestType;
|
||||
import com.theoryinpractice.testng.ui.TestNGConsoleView;
|
||||
import com.theoryinpractice.testng.ui.TestNGResults;
|
||||
import com.theoryinpractice.testng.ui.actions.RerunFailedTestsAction;
|
||||
@@ -72,9 +76,11 @@ import org.testng.annotations.AfterClass;
|
||||
import org.testng.remote.strprotocol.MessageHelper;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
public class TestNGRunnableState extends JavaCommandLineState {
|
||||
@@ -86,6 +92,7 @@ public class TestNGRunnableState extends JavaCommandLineState {
|
||||
private int port;
|
||||
private String debugPort;
|
||||
private File myTempFile;
|
||||
private BackgroundableProcessIndicator mySearchForTestIndicator;
|
||||
|
||||
public TestNGRunnableState(ExecutionEnvironment environment, TestNGConfiguration config) {
|
||||
super(environment);
|
||||
@@ -114,9 +121,18 @@ public class TestNGRunnableState extends JavaCommandLineState {
|
||||
|
||||
@Override
|
||||
public ExecutionResult execute(@NotNull final Executor executor, @NotNull final ProgramRunner runner) throws ExecutionException {
|
||||
OSProcessHandler processHandler = null;
|
||||
try {
|
||||
processHandler = startProcess();
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
if (mySearchForTestIndicator != null && !mySearchForTestIndicator.isCanceled()) {
|
||||
mySearchForTestIndicator.cancel();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
final TestNGConsoleView console = new TestNGConsoleView(config, runnerSettings, myConfigurationPerRunnerSettings);
|
||||
console.initUI();
|
||||
OSProcessHandler processHandler = startProcess();
|
||||
for (RunConfigurationExtension ext : Extensions.getExtensions(RunConfigurationExtension.EP_NAME)) {
|
||||
ext.handleStartProcess(config, processHandler);
|
||||
}
|
||||
@@ -306,7 +322,22 @@ public class TestNGRunnableState extends JavaCommandLineState {
|
||||
myTempFile = File.createTempFile("idea_testng", ".tmp");
|
||||
myTempFile.deleteOnExit();
|
||||
javaParameters.getProgramParametersList().add("-temp", myTempFile.getAbsolutePath());
|
||||
ProgressManager.getInstance().run(new SearchingForTestsTask(serverSocket, is15, config, myTempFile));
|
||||
final SearchingForTestsTask task = new SearchingForTestsTask(serverSocket, is15, config, myTempFile);
|
||||
mySearchForTestIndicator = new BackgroundableProcessIndicator(task) {
|
||||
@Override
|
||||
public void cancel() {
|
||||
try {//ensure that serverSocket.accept was interrupted
|
||||
if (!serverSocket.isClosed()) {
|
||||
new Socket(InetAddress.getLocalHost(), serverSocket.getLocalPort());
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
super.cancel();
|
||||
}
|
||||
};
|
||||
ProgressManagerImpl.runProcessWithProgressAsynchronously(task, mySearchForTestIndicator);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
|
||||
@@ -19,9 +19,13 @@ package com.intellij.codeInsight.template.zencoding;
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
class NumberToken extends Token {
|
||||
final int myNumber;
|
||||
private final int myNumber;
|
||||
|
||||
NumberToken(int number) {
|
||||
myNumber = number;
|
||||
}
|
||||
|
||||
public int getNumber() {
|
||||
return myNumber;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,13 @@ package com.intellij.codeInsight.template.zencoding;
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
class OperationToken extends Token {
|
||||
final char mySign;
|
||||
private final char mySign;
|
||||
|
||||
OperationToken(char sign) {
|
||||
mySign = sign;
|
||||
}
|
||||
|
||||
public char getSign() {
|
||||
return mySign;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.template.zencoding;
|
||||
|
||||
import com.intellij.codeInsight.template.impl.TemplateImpl;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -27,6 +28,7 @@ public class TemplateToken extends Token {
|
||||
private final String myKey;
|
||||
private final List<Pair<String, String>> myAttribute2Value;
|
||||
private TemplateImpl myTemplate;
|
||||
private XmlTag myTag;
|
||||
|
||||
public TemplateToken(String key, List<Pair<String, String>> attribute2value) {
|
||||
myKey = key;
|
||||
@@ -48,4 +50,12 @@ public class TemplateToken extends Token {
|
||||
public TemplateImpl getTemplate() {
|
||||
return myTemplate;
|
||||
}
|
||||
|
||||
public XmlTag getTag() {
|
||||
return myTag;
|
||||
}
|
||||
|
||||
public void setTag(XmlTag tag) {
|
||||
myTag = tag;
|
||||
}
|
||||
}
|
||||
|
||||
+47
-97
@@ -25,18 +25,13 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.xml.XmlChildRole;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.psi.xml.XmlToken;
|
||||
import com.intellij.psi.xml.XmlTokenType;
|
||||
import com.intellij.psi.xml.*;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.containers.IntArrayList;
|
||||
import com.intellij.xml.util.HtmlUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -79,7 +74,7 @@ class XmlZenCodingInterpreter {
|
||||
PsiFile file = myCallback.parseCurrentText(StdFileTypes.XML);
|
||||
|
||||
PsiElement element = file.findElementAt(offset);
|
||||
if (element instanceof XmlToken && ((XmlToken)element).getTokenType() == XmlTokenType.XML_END_TAG_START) {
|
||||
if (offset < endOfTemplate && element instanceof XmlToken && ((XmlToken)element).getTokenType() == XmlTokenType.XML_END_TAG_START) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -94,7 +89,9 @@ class XmlZenCodingInterpreter {
|
||||
}
|
||||
|
||||
if (newOffset >= 0) {
|
||||
myCallback.fixEndOffset();
|
||||
if (offset < endOfTemplate) {
|
||||
myCallback.fixEndOffset();
|
||||
}
|
||||
myCallback.moveToOffset(newOffset);
|
||||
}
|
||||
}
|
||||
@@ -121,7 +118,7 @@ class XmlZenCodingInterpreter {
|
||||
case OPERATION:
|
||||
if (templateToken != null) {
|
||||
if (token instanceof MarkerToken || token instanceof OperationToken) {
|
||||
final char sign = token instanceof OperationToken ? ((OperationToken)token).mySign : ZenCodingTemplate.MARKER;
|
||||
final char sign = token instanceof OperationToken ? ((OperationToken)token).getSign() : ZenCodingTemplate.MARKER;
|
||||
if (sign == '+' || (mySurroundedText == null && sign == ZenCodingTemplate.MARKER)) {
|
||||
final Object key = new Object();
|
||||
myCallback.fixStartOfTemplate(key);
|
||||
@@ -159,7 +156,7 @@ class XmlZenCodingInterpreter {
|
||||
break;
|
||||
case NUMBER:
|
||||
if (token instanceof NumberToken) {
|
||||
number = ((NumberToken)token).myNumber;
|
||||
number = ((NumberToken)token).getNumber();
|
||||
myState = State.AFTER_NUMBER;
|
||||
}
|
||||
else {
|
||||
@@ -168,7 +165,7 @@ class XmlZenCodingInterpreter {
|
||||
break;
|
||||
case AFTER_NUMBER:
|
||||
if (token instanceof MarkerToken || token instanceof OperationToken) {
|
||||
char sign = token instanceof OperationToken ? ((OperationToken)token).mySign : ZenCodingTemplate.MARKER;
|
||||
char sign = token instanceof OperationToken ? ((OperationToken)token).getSign() : ZenCodingTemplate.MARKER;
|
||||
if (sign == '+' || (mySurroundedText == null && sign == ZenCodingTemplate.MARKER)) {
|
||||
invokeTemplateSeveralTimes(templateToken, 0, number);
|
||||
templateToken = null;
|
||||
@@ -231,8 +228,10 @@ class XmlZenCodingInterpreter {
|
||||
final Object key = new Object();
|
||||
myCallback.fixStartOfTemplate(key);
|
||||
for (int i = startIndex; i < count; i++) {
|
||||
Object iterKey = new Object();
|
||||
myCallback.fixStartOfTemplate(iterKey);
|
||||
invokeTemplate(templateToken, myCallback, i);
|
||||
gotoChild(key);
|
||||
gotoChild(iterKey);
|
||||
interpret(myTokens, tailStart, myCallback, State.WORD, mySurroundedText);
|
||||
if (myCallback.getOffset() != myCallback.getEndOfTemplate(key)) {
|
||||
myCallback.fixEndOffset();
|
||||
@@ -242,7 +241,7 @@ class XmlZenCodingInterpreter {
|
||||
finish();
|
||||
}
|
||||
|
||||
private static boolean containsAttrsVar(TemplateImpl template) {
|
||||
static boolean containsAttrsVar(TemplateImpl template) {
|
||||
for (int i = 0; i < template.getVariableCount(); i++) {
|
||||
String varName = template.getVariableNameAt(i);
|
||||
if (ATTRS.equals(varName)) {
|
||||
@@ -271,17 +270,7 @@ class XmlZenCodingInterpreter {
|
||||
|
||||
@Nullable
|
||||
private static Map<String, String> buildPredefinedValues(List<Pair<String, String>> attribute2value, int numberInIteration) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (Iterator<Pair<String, String>> it = attribute2value.iterator(); it.hasNext();) {
|
||||
Pair<String, String> pair = it.next();
|
||||
String name = pair.first;
|
||||
String value = getValue(pair, numberInIteration);
|
||||
result.append(name).append("=\"").append(value).append('"');
|
||||
if (it.hasNext()) {
|
||||
result.append(' ');
|
||||
}
|
||||
}
|
||||
String attributes = result.toString();
|
||||
String attributes = buildAttributesString(attribute2value, numberInIteration);
|
||||
attributes = attributes.length() > 0 ? ' ' + attributes : null;
|
||||
Map<String, String> predefinedValues = null;
|
||||
if (attributes != null) {
|
||||
@@ -291,66 +280,37 @@ class XmlZenCodingInterpreter {
|
||||
return predefinedValues;
|
||||
}
|
||||
|
||||
private static String getValue(Pair<String, String> pair, int numberInIteration) {
|
||||
return pair.second.replace(NUMBER_IN_ITERATION_PLACE_HOLDER, Integer.toString(numberInIteration + 1));
|
||||
@NotNull
|
||||
private static String buildAttributesString(List<Pair<String, String>> attribute2value, int numberInIteration) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (Iterator<Pair<String, String>> it = attribute2value.iterator(); it.hasNext();) {
|
||||
Pair<String, String> pair = it.next();
|
||||
String name = pair.first;
|
||||
String value = getValue(pair, numberInIteration);
|
||||
result.append(getAttributeString(name, value));
|
||||
if (it.hasNext()) {
|
||||
result.append(' ');
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String addAttrsVar(TemplateImpl modifiedTemplate, XmlTag tag) {
|
||||
String text = tag.getContainingFile().getText();
|
||||
PsiElement[] children = tag.getChildren();
|
||||
if (children.length >= 1 &&
|
||||
children[0] instanceof XmlToken &&
|
||||
((XmlToken)children[0]).getTokenType() == XmlTokenType.XML_START_TAG_START) {
|
||||
PsiElement beforeAttrs = children[0];
|
||||
if (children.length >= 2 && children[1] instanceof XmlToken && ((XmlToken)children[1]).getTokenType() == XmlTokenType.XML_NAME) {
|
||||
beforeAttrs = children[1];
|
||||
}
|
||||
TextRange range = beforeAttrs.getTextRange();
|
||||
if (range == null) {
|
||||
return null;
|
||||
}
|
||||
int offset = range.getEndOffset();
|
||||
text = text.substring(0, offset) + " $ATTRS$" + text.substring(offset);
|
||||
modifiedTemplate.addVariable(ATTRS, "", "", false);
|
||||
return text;
|
||||
}
|
||||
return null;
|
||||
private static String getAttributeString(String name, String value) {
|
||||
return name + "=\"" + value + '"';
|
||||
}
|
||||
|
||||
private static String getValue(Pair<String, String> pair, int numberInIteration) {
|
||||
return pair.second.replace(NUMBER_IN_ITERATION_PLACE_HOLDER, Integer.toString(numberInIteration + 1));
|
||||
}
|
||||
|
||||
private static void invokeTemplate(TemplateToken token,
|
||||
final CustomTemplateCallback callback,
|
||||
int numberInIteration) {
|
||||
List<Pair<String, String>> attr2value = new ArrayList<Pair<String, String>>(token.getAttribute2Value());
|
||||
if (callback.isLiveTemplateApplicable(token.getKey())) {
|
||||
invokeExistingLiveTemplate(token, callback, numberInIteration, attr2value);
|
||||
}
|
||||
else {
|
||||
TemplateImpl template = new TemplateImpl("", "");
|
||||
template.addTextSegment('<' + token.getKey());
|
||||
if (attr2value.size() > 0) {
|
||||
template.addVariable(ATTRS, "", "", false);
|
||||
template.addVariableSegment(ATTRS);
|
||||
}
|
||||
template.addTextSegment(">");
|
||||
if (XmlZenCodingTemplate.isTrueXml(callback) || !HtmlUtil.isSingleHtmlTag(token.getKey())) {
|
||||
template.addVariableSegment(TemplateImpl.END);
|
||||
template.addTextSegment("</" + token.getKey() + ">");
|
||||
}
|
||||
template.setToReformat(true);
|
||||
Map<String, String> predefinedValues = buildPredefinedValues(attr2value, numberInIteration);
|
||||
callback.expandTemplate(template, predefinedValues);
|
||||
}
|
||||
}
|
||||
|
||||
private static void invokeExistingLiveTemplate(TemplateToken token,
|
||||
CustomTemplateCallback callback,
|
||||
int numberInIteration,
|
||||
List<Pair<String, String>> attr2value) {
|
||||
if (token.getTemplate() != null) {
|
||||
if (attr2value.size() > 0 || XmlZenCodingTemplate.isTrueXml(callback)) {
|
||||
TemplateImpl modifiedTemplate = token.getTemplate().copy();
|
||||
XmlTag tag = XmlZenCodingTemplate.parseXmlTagInTemplate(token.getTemplate().getString(), callback, true);
|
||||
XmlTag tag = token.getTag();
|
||||
if (tag != null) {
|
||||
for (Iterator<Pair<String, String>> iterator = attr2value.iterator(); iterator.hasNext();) {
|
||||
Pair<String, String> pair = iterator.next();
|
||||
@@ -359,27 +319,7 @@ class XmlZenCodingInterpreter {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
if (XmlZenCodingTemplate.isTrueXml(callback)) {
|
||||
closeUnclosingTags(tag);
|
||||
}
|
||||
String text = null;
|
||||
if (!containsAttrsVar(modifiedTemplate) && attr2value.size() > 0) {
|
||||
String textWithAttrs = addAttrsVar(modifiedTemplate, tag);
|
||||
if (textWithAttrs != null) {
|
||||
text = textWithAttrs;
|
||||
}
|
||||
else {
|
||||
for (Iterator<Pair<String, String>> iterator = attr2value.iterator(); iterator.hasNext();) {
|
||||
Pair<String, String> pair = iterator.next();
|
||||
tag.setAttribute(pair.first, getValue(pair, numberInIteration));
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (text == null) {
|
||||
text = tag.getContainingFile().getText();
|
||||
}
|
||||
modifiedTemplate.setString(text);
|
||||
modifiedTemplate.setString(filter(tag, callback));
|
||||
removeVariablesWhichHasNoSegment(modifiedTemplate);
|
||||
Map<String, String> predefinedValues = buildPredefinedValues(attr2value, numberInIteration);
|
||||
callback.expandTemplate(modifiedTemplate, predefinedValues);
|
||||
@@ -389,11 +329,19 @@ class XmlZenCodingInterpreter {
|
||||
callback.expandTemplate(token.getTemplate(), null);
|
||||
}
|
||||
else {
|
||||
// for CSS
|
||||
Map<String, String> predefinedValues = buildPredefinedValues(attr2value, numberInIteration);
|
||||
callback.expandTemplate(token.getKey(), predefinedValues);
|
||||
}
|
||||
}
|
||||
|
||||
private static String filter(XmlTag tag, CustomTemplateCallback callback) {
|
||||
if (XmlZenCodingTemplate.isTrueXml(callback)) {
|
||||
closeUnclosingTags(tag);
|
||||
}
|
||||
return tag.getContainingFile().getText();
|
||||
}
|
||||
|
||||
private static boolean isTagClosed(@NotNull XmlTag tag) {
|
||||
ASTNode node = tag.getNode();
|
||||
assert node != null;
|
||||
@@ -406,15 +354,16 @@ class XmlZenCodingInterpreter {
|
||||
private static void closeUnclosingTags(@NotNull XmlTag root) {
|
||||
final List<SmartPsiElementPointer<XmlTag>> tagToClose = new ArrayList<SmartPsiElementPointer<XmlTag>>();
|
||||
Project project = root.getProject();
|
||||
final SmartPointerManager manager = SmartPointerManager.getInstance(project);
|
||||
final SmartPointerManager pointerManager = SmartPointerManager.getInstance(project);
|
||||
root.accept(new XmlRecursiveElementVisitor() {
|
||||
@Override
|
||||
public void visitXmlTag(final XmlTag tag) {
|
||||
if (!isTagClosed(tag)) {
|
||||
tagToClose.add(manager.createLazyPointer(tag));
|
||||
tagToClose.add(pointerManager.createLazyPointer(tag));
|
||||
}
|
||||
}
|
||||
});
|
||||
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
|
||||
for (final SmartPsiElementPointer<XmlTag> pointer : tagToClose) {
|
||||
final XmlTag tag = pointer.getElement();
|
||||
if (tag != null) {
|
||||
@@ -424,6 +373,7 @@ class XmlZenCodingInterpreter {
|
||||
VirtualFile file = tag.getContainingFile().getVirtualFile();
|
||||
if (file != null) {
|
||||
final Document document = FileDocumentManager.getInstance().getDocument(file);
|
||||
documentManager.doPostponedOperationsAndUnblockDocument(document);
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
document.replaceString(offset, tag.getTextRange().getEndOffset(), "/>");
|
||||
@@ -433,7 +383,7 @@ class XmlZenCodingInterpreter {
|
||||
}
|
||||
}
|
||||
}
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments();
|
||||
documentManager.commitAllDocuments();
|
||||
}
|
||||
|
||||
private static void fail() {
|
||||
|
||||
@@ -27,15 +27,18 @@ import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiFileFactory;
|
||||
import com.intellij.psi.XmlElementFactory;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.xml.*;
|
||||
import com.intellij.util.LocalTimeCounter;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.xml.util.HtmlUtil;
|
||||
import org.apache.xerces.util.XML11Char;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -192,19 +195,60 @@ public class XmlZenCodingTemplate extends ZenCodingTemplate {
|
||||
if (useDefaultTag && token.getAttribute2Value().size() == 0) {
|
||||
return null;
|
||||
}
|
||||
if (template != null && (token.getAttribute2Value().size() > 0 || isTrueXml(callback))) {
|
||||
assert prefix.equals(token.getKey());
|
||||
token.setTemplate(template);
|
||||
if (token.getAttribute2Value().size() > 0) {
|
||||
XmlTag tag = parseXmlTagInTemplate(template.getString(), callback, false);
|
||||
if (tag == null) {
|
||||
return null;
|
||||
}
|
||||
if (template == null) {
|
||||
template = generateTagTemplate(token.getKey(), callback);
|
||||
}
|
||||
assert prefix.equals(token.getKey());
|
||||
token.setTemplate(template);
|
||||
XmlTag tag = parseXmlTagInTemplate(template.getString(), callback, true);
|
||||
if (token.getAttribute2Value().size() > 0 && tag == null) {
|
||||
return null;
|
||||
}
|
||||
if (tag != null) {
|
||||
if (!XmlZenCodingInterpreter.containsAttrsVar(template) && token.getAttribute2Value().size() > 0) {
|
||||
addMissingAttributes(tag, token.getAttribute2Value());
|
||||
}
|
||||
token.setTag(tag);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
private static void addMissingAttributes(XmlTag tag, List<Pair<String, String>> value) {
|
||||
List<Pair<String, String>> attr2value = new ArrayList<Pair<String, String>>(value);
|
||||
for (Iterator<Pair<String, String>> iterator = attr2value.iterator(); iterator.hasNext();) {
|
||||
Pair<String, String> pair = iterator.next();
|
||||
if (tag.getAttribute(pair.first) != null) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
addAttributesBefore(tag, attr2value);
|
||||
}
|
||||
|
||||
private static void addAttributesBefore(XmlTag tag, List<Pair<String, String>> attr2value) {
|
||||
XmlAttribute[] attributes = tag.getAttributes();
|
||||
XmlAttribute firstAttribute = attributes.length > 0 ? attributes[0] : null;
|
||||
XmlElementFactory factory = XmlElementFactory.getInstance(tag.getProject());
|
||||
for (Pair<String, String> pair : attr2value) {
|
||||
XmlAttribute xmlAttribute = factory.createXmlAttribute(pair.first, "");
|
||||
if (firstAttribute != null) {
|
||||
tag.addBefore(xmlAttribute, firstAttribute);
|
||||
}
|
||||
else {
|
||||
tag.add(xmlAttribute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static TemplateImpl generateTagTemplate(String tagName, CustomTemplateCallback callback) {
|
||||
StringBuilder builder = new StringBuilder("<");
|
||||
builder.append(tagName).append('>');
|
||||
if (isTrueXml(callback) || !HtmlUtil.isSingleHtmlTag(tagName)) {
|
||||
builder.append("$END$</").append(tagName).append('>');
|
||||
}
|
||||
return new TemplateImpl("", builder.toString(), "");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static XmlTag parseXmlTagInTemplate(String templateString, CustomTemplateCallback callback, boolean createPhysicalFile) {
|
||||
XmlFile xmlFile = (XmlFile)PsiFileFactory.getInstance(callback.getProject())
|
||||
|
||||
@@ -96,7 +96,7 @@ public abstract class ZenCodingTemplate implements CustomLiveTemplate {
|
||||
switch (state) {
|
||||
case OPERATION:
|
||||
if (token instanceof OperationToken) {
|
||||
state = ((OperationToken)token).mySign == '*' ? State.NUMBER : State.WORD;
|
||||
state = ((OperationToken)token).getSign() == '*' ? State.NUMBER : State.WORD;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
@@ -119,7 +119,7 @@ public abstract class ZenCodingTemplate implements CustomLiveTemplate {
|
||||
}
|
||||
break;
|
||||
case AFTER_NUMBER:
|
||||
if (token instanceof OperationToken && ((OperationToken)token).mySign != '*') {
|
||||
if (token instanceof OperationToken && ((OperationToken)token).getSign() != '*') {
|
||||
state = State.WORD;
|
||||
}
|
||||
else {
|
||||
@@ -154,16 +154,6 @@ public abstract class ZenCodingTemplate implements CustomLiveTemplate {
|
||||
protected boolean checkTemplateKey(String key, CustomTemplateCallback callback) {
|
||||
List<Token> tokens = parse(key, callback);
|
||||
if (tokens != null && check(tokens)) {
|
||||
// !! required if Zen Coding if invoked by TemplateManagerImpl action
|
||||
/*if (tokens.size() == 2) {
|
||||
Token token = tokens.get(0);
|
||||
if (token instanceof TemplateToken) {
|
||||
if (key.equals(((TemplateToken)token).myKey) && callback.isLiveTemplateApplicable(key)) {
|
||||
// do not activate only live template
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user