Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ekaterina Tuzova
2013-12-03 19:24:39 +04:00
81 changed files with 1336 additions and 785 deletions
@@ -25,10 +25,7 @@ import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleRootAdapter;
import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
@@ -74,7 +71,13 @@ public class SetupSDKNotificationProvider extends EditorNotifications.Provider<E
return null;
}
if (ProjectRootManager.getInstance(myProject).getProjectSdk() != null) {
Module module = ModuleUtilCore.findModuleForPsiElement(psiFile);
if (module == null) {
return null;
}
Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
if (sdk != null) {
return null;
}
@@ -292,11 +292,14 @@ public class AnnotationsHighlightUtil {
private static final ElementPattern<PsiElement> ANY_ANNOTATION_ALLOWED = psiElement().andOr(
psiElement().withParent(PsiNameValuePair.class),
psiElement().withParents(PsiArrayInitializerMemberValue.class, PsiNameValuePair.class),
psiElement().withParents(PsiArrayInitializerMemberValue.class, PsiAnnotationMethod.class),
psiElement().withParent(PsiAnnotationMethod.class).afterLeaf(PsiKeyword.DEFAULT)
);
@Nullable
public static HighlightInfo checkApplicability(@NotNull PsiAnnotation annotation, @NotNull LanguageLevel languageLevel,@NotNull PsiFile containingFile) {
public static HighlightInfo checkApplicability(@NotNull PsiAnnotation annotation,
@NotNull LanguageLevel languageLevel,
@NotNull PsiFile containingFile) {
if (ANY_ANNOTATION_ALLOWED.accepts(annotation)) {
return null;
}
@@ -29,7 +29,6 @@ import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.JavaVersionService;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.pom.java.LanguageLevel;
@@ -202,7 +201,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
public void visitAnnotation(PsiAnnotation annotation) {
super.visitAnnotation(annotation);
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAnnotationFeature(annotation, myLanguageLevel, myFile));
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkApplicability(annotation, myLanguageLevel,myFile));
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkApplicability(annotation, myLanguageLevel, myFile));
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkAnnotationType(annotation));
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkMissingAttributes(annotation));
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkTargetAnnotationDuplicates(annotation));
@@ -1240,7 +1239,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
}
}
}
if (!myHolder.hasErrorResults()) {
myHolder.add(PsiMethodReferenceHighlightingUtil.checkRawConstructorReference(expression));
}
@@ -94,6 +94,10 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
return null;
}
PsiElement parent = codeFragment.getParent();
if (parent instanceof PsiLambdaExpression && codeFragment instanceof PsiExpression) {
addInstruction(new CheckReturnValueInstruction(codeFragment));
}
myCurrentFlow.setFields(myFields.toArray(new DfaVariableValue[myFields.size()]));
addInstruction(new ReturnInstruction(false));
@@ -528,6 +532,15 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
finishElement(statement);
}
@Override
public void visitLambdaExpression(PsiLambdaExpression expression) {
startElement(expression);
DfaValue dfaValue = myFactory.createValue(expression);
addInstruction(new PushInstruction(dfaValue, expression));
addInstruction(new LambdaInstruction(expression));
finishElement(expression);
}
@Override public void visitReturnStatement(PsiReturnStatement statement) {
startElement(statement);
@@ -538,7 +551,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
if (method != null) {
generateBoxingUnboxingInstructionFor(returnValue, method.getReturnType());
}
addInstruction(new CheckReturnValueInstruction(statement));
addInstruction(new CheckReturnValueInstruction(returnValue));
}
returnCheckingFinally();
@@ -479,8 +479,8 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool {
private static void reportNullableReturns(StandardDataFlowRunner runner, DataFlowInstructionVisitor visitor, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
for (PsiElement statement : visitor.getProblems(NullabilityProblem.nullableReturn)) {
final PsiExpression expr = ((PsiReturnStatement)statement).getReturnValue();
assert expr != null;
assert statement instanceof PsiExpression;
final PsiExpression expr = (PsiExpression)statement;
if (!reportedAnchors.add(expr)) continue;
if (runner.isInNotNullMethod()) {
@@ -226,6 +226,10 @@ public class DataFlowRunner {
}
}
}
else if (instruction instanceof LambdaInstruction) {
PsiLambdaExpression lambdaExpression = ((LambdaInstruction)instruction).getLambdaExpression();
registerNestedClosures(instructionState, lambdaExpression);
}
else if (instruction instanceof EmptyInstruction) {
PsiElement anchor = ((EmptyInstruction)instruction).getAnchor();
if (anchor instanceof PsiDeclarationStatement) {
@@ -255,6 +259,14 @@ public class DataFlowRunner {
myNestedClosures.putValue(field, createClosureState(state));
}
}
private void registerNestedClosures(DfaInstructionState instructionState, PsiLambdaExpression expr) {
DfaMemoryState state = instructionState.getMemoryState();
PsiElement body = expr.getBody();
if (body != null) {
myNestedClosures.putValue(body, createClosureState(state));
}
}
protected ControlFlowAnalyzer createControlFlowAnalyzer() {
return new ControlFlowAnalyzer(myValueFactory);
@@ -54,6 +54,10 @@ public abstract class InstructionVisitor {
return nextInstruction(instruction, runner, memState);
}
public DfaInstructionState[] visitLambdaExpression(LambdaInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
return nextInstruction(instruction, runner, memState);
}
public DfaInstructionState[] visitConditionalGoto(ConditionalGotoInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
DfaValue cond = memState.pop();
@@ -27,10 +27,7 @@ package com.intellij.codeInspection.dataFlow;
import com.intellij.codeInsight.NullableNotNullManager;
import com.intellij.codeInspection.dataFlow.instructions.InstanceofInstruction;
import com.intellij.codeInspection.dataFlow.instructions.Instruction;
import com.intellij.psi.CommonClassNames;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiType;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
@@ -49,13 +46,23 @@ public class StandardDataFlowRunner extends DataFlowRunner {
@Override
protected void prepareAnalysis(@NotNull PsiElement psiBlock, Iterable<DfaMemoryState> initialStates) {
myIsInMethod = psiBlock.getParent() instanceof PsiMethod;
PsiElement parent = psiBlock.getParent();
myIsInMethod = parent instanceof PsiMethod;
if (myIsInMethod) {
PsiMethod method = (PsiMethod)psiBlock.getParent();
PsiMethod method = (PsiMethod)parent;
PsiType returnType = method.getReturnType();
myInNullableMethod = NullableNotNullManager.isNullable(method) ||
returnType != null && returnType.equalsToText(CommonClassNames.JAVA_LANG_VOID);
myInNotNullMethod = NullableNotNullManager.isNotNull(method);
} else if (parent instanceof PsiLambdaExpression) {
PsiMethod method = LambdaUtil.getFunctionalInterfaceMethod(((PsiLambdaExpression)parent).getFunctionalInterfaceType());
if (method != null) {
myIsInMethod = true;
PsiType returnType = method.getReturnType();
myInNullableMethod = NullableNotNullManager.isNullable(method) ||
returnType != null && returnType.equalsToText(CommonClassNames.JAVA_LANG_VOID);
myInNotNullMethod = NullableNotNullManager.isNotNull(method);
}
}
myCCEInstructions.clear();
@@ -19,16 +19,16 @@ import com.intellij.codeInspection.dataFlow.DataFlowRunner;
import com.intellij.codeInspection.dataFlow.DfaInstructionState;
import com.intellij.codeInspection.dataFlow.DfaMemoryState;
import com.intellij.codeInspection.dataFlow.InstructionVisitor;
import com.intellij.psi.PsiReturnStatement;
import com.intellij.psi.PsiElement;
/**
* @author max
*/
public class CheckReturnValueInstruction extends Instruction {
private final PsiReturnStatement myReturn;
private final PsiElement myReturnValue;
public CheckReturnValueInstruction(final PsiReturnStatement aReturn) {
myReturn = aReturn;
public CheckReturnValueInstruction(final PsiElement returnValue) {
myReturnValue = returnValue;
}
@Override
@@ -36,8 +36,8 @@ public class CheckReturnValueInstruction extends Instruction {
return visitor.visitCheckReturnValue(this, runner, stateBefore);
}
public PsiReturnStatement getReturn() {
return myReturn;
public PsiElement getReturn() {
return myReturnValue;
}
public String toString() {
@@ -0,0 +1,44 @@
/*
* Copyright 2000-2013 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.codeInspection.dataFlow.instructions;
import com.intellij.codeInspection.dataFlow.DataFlowRunner;
import com.intellij.codeInspection.dataFlow.DfaInstructionState;
import com.intellij.codeInspection.dataFlow.DfaMemoryState;
import com.intellij.codeInspection.dataFlow.InstructionVisitor;
import com.intellij.psi.PsiLambdaExpression;
public class LambdaInstruction extends Instruction {
private final PsiLambdaExpression myLambdaExpression;
public LambdaInstruction(PsiLambdaExpression lambdaExpression) {
myLambdaExpression = lambdaExpression;
}
public PsiLambdaExpression getLambdaExpression() {
return myLambdaExpression;
}
@Override
public DfaInstructionState[] accept(DataFlowRunner runner, DfaMemoryState stateBefore, InstructionVisitor visitor) {
return visitor.visitLambdaExpression(this, runner, stateBefore);
}
@Override
public String toString() {
return "LambdaInstruction";
}
}
@@ -30,10 +30,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.NullableLazyKey;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PsiJavaPatterns;
@@ -449,7 +446,7 @@ public class JavaCompletionUtil {
PsiSubstitutor plainSub = plainResult.getSubstitutor();
PsiSubstitutor castSub = TypeConversionUtil.getSuperClassSubstitutor(plainClass, (PsiClassType)castType);
if (method.getSignature(plainSub).equals(method.getSignature(castSub)) &&
plainSub.substitute(method.getReturnType()).equals(castSub.substitute(method.getReturnType())) &&
Comparing.equal(plainSub.substitute(method.getReturnType()), castSub.substitute(method.getReturnType())) &&
processor.isAccessible(plainClass.findMethodBySignature(method, true))
) {
return item;
@@ -22,12 +22,14 @@ import com.intellij.codeInsight.intention.QuickFixFactory;
import com.intellij.codeInsight.intention.impl.PriorityIntentionActionWrapper;
import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.EnumMap;
import java.util.Map;
@@ -100,7 +102,7 @@ public class DefaultQuickFixProvider extends UnresolvedReferenceQuickFixProvider
}
}
@NotNull
@Nullable
private static VariableKind getKind(@NotNull JavaCodeStyleManager styleManager, @NotNull PsiReferenceExpression refExpr) {
final String reference = refExpr.getText();
@@ -121,6 +123,10 @@ public class DefaultQuickFixProvider extends UnresolvedReferenceQuickFixProvider
}
}
if (StringUtil.isCapitalized(reference)) {
return null;
}
return VariableKind.LOCAL_VARIABLE;
}
@@ -1270,10 +1270,11 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
PsiExpression lExpr = PsiUtil.skipParenthesizedExprDown(expression.getLExpression());
if (lExpr instanceof PsiReferenceExpression) {
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)lExpr;
if (!referenceExpression.isQualified()
|| referenceExpression.getQualifierExpression() instanceof PsiThisExpression) {
PsiVariable variable = getUsedVariable(referenceExpression);
PsiExpression qualifierExpression = referenceExpression.getQualifierExpression();
PsiVariable variable = getUsedVariable(referenceExpression);
if (qualifierExpression == null ||
qualifierExpression instanceof PsiThisExpression ||
variable instanceof PsiField && variable.hasModifierProperty(PsiModifier.STATIC)) {
if (variable != null) {
if (myAssignmentTargetsAreElements)
startElement(lExpr);
@@ -1285,7 +1286,6 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
if (myAssignmentTargetsAreElements) finishElement(lExpr);
}
}
else {
lExpr.accept(this); //?
@@ -37,14 +37,13 @@ import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.util.MethodSignature;
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.*;
import com.intellij.reference.SoftReference;
import com.intellij.ui.RowIcon;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.List;
@@ -311,7 +310,17 @@ public class PsiMethodImpl extends JavaStubPsiElement<PsiMethodStub> implements
@Override
@NotNull
public MethodSignature getSignature(@NotNull PsiSubstitutor substitutor){
public MethodSignature getSignature(@NotNull PsiSubstitutor substitutor) {
if (substitutor == PsiSubstitutor.EMPTY) {
return CachedValuesManager.getCachedValue(this, new CachedValueProvider<MethodSignature>() {
@Nullable
@Override
public Result<MethodSignature> compute() {
MethodSignature signature = MethodSignatureBackedByPsiMethod.create(PsiMethodImpl.this, PsiSubstitutor.EMPTY);
return Result.create(signature, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
}
});
}
return MethodSignatureBackedByPsiMethod.create(this, substitutor);
}
@@ -27,4 +27,10 @@ interface I {
@interface Caller {
Anno anno() default @Anno;
}
}
@interface AnnoArray {
@interface Part { }
Part[] arrayValue() default {@Part, @Part};
}
@@ -0,0 +1,12 @@
import org.jetbrains.annotations.NotNull;
class Test {
interface I {
@NotNull
String get();
}
{
I i = () -> <warning descr="'null' is returned by the method declared as @NotNull">null</warning>;
}
}
@@ -0,0 +1,12 @@
import org.jetbrains.annotations.NotNull;
class Test {
interface I {
@NotNull
String get();
}
{
I i = () -> {return <warning descr="'null' is returned by the method declared as @NotNull">null</warning>;};
}
}
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
</problems>
@@ -0,0 +1,7 @@
class G{
private static boolean foo = true;
static void bar(){
if(foo)
G.foo = false;
}
}
@@ -45,6 +45,14 @@ public class DataFlowInspection8Test extends LightCodeInsightFixtureTestCase {
doTest();
}
public void testReturnNullInLambdaExpression() throws Exception {
doTest();
}
public void testReturnNullInLambdaStatement() throws Exception {
doTest();
}
private void setupCustomAnnotations() {
myFixture.addClass("package foo;\n\nimport java.lang.annotation.*;\n\n@Target({ElementType.TYPE_USE}) public @interface Nullable { }");
myFixture.addClass("package foo;\n\nimport java.lang.annotation.*;\n\n@Target({ElementType.TYPE_USE}) public @interface NotNull { }");
@@ -38,6 +38,7 @@ public class FieldCanBeLocalTest extends InspectionTestCase {
public void testFieldUsedInConstantInitialization() throws Exception {doTest();}
public void testFieldWithImmutableType() throws Exception {doTest();}
public void testFieldUsedForWritingInLambda() throws Exception {doTest();}
public void testStaticQualifiedFieldAccessForWriting() throws Exception {doTest();}
public void testIgnoreAnnotated() throws Exception {
final FieldCanBeLocalInspection inspection = new FieldCanBeLocalInspection();
doTestConfigured(inspection);
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.vfs.impl.http;
import com.intellij.openapi.util.AsyncResult;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
@@ -34,4 +35,7 @@ public interface RemoteFileInfo {
RemoteFileState getState();
void cancelDownloading();
@NotNull
AsyncResult<VirtualFile> download();
}
@@ -116,7 +116,7 @@ public abstract class StubProcessingHelperBase {
/***
* Returns a message to log when stub tree and index do not match
*/
protected abstract String stubTreeAndIndexDoNotMatch(StubTree stubTree,
protected abstract Object stubTreeAndIndexDoNotMatch(StubTree stubTree,
PsiFileWithStubSupport psiFile,
List<StubElement<?>> plained,
VirtualFile virtualFile,
@@ -35,7 +35,7 @@ public class StubProcessingHelper extends StubProcessingHelperBase {
@Override
protected String stubTreeAndIndexDoNotMatch(StubTree stubTree,
protected Object stubTreeAndIndexDoNotMatch(StubTree stubTree,
PsiFileWithStubSupport psiFile,
List<StubElement<?>> plained,
VirtualFile virtualFile,
@@ -51,6 +51,6 @@ public class StubProcessingHelper extends StubProcessingHelperBase {
new Attachment("stubTree.txt", ((PsiFileStubImpl)stubTree.getRoot()).printTree()),
new Attachment("stubTreeFromIndex.txt", stubTreeFromIndex == null
? "null"
: ((PsiFileStubImpl)stubTreeFromIndex.getRoot()).printTree())).toString();
: ((PsiFileStubImpl)stubTreeFromIndex.getRoot()).printTree()));
}
}
@@ -2061,67 +2061,42 @@ public class FileBasedIndexImpl extends FileBasedIndex {
cleanProcessedFlag(file);
IndexingStamp.flushCache(file);
final List<ID<?, ?>> affectedIndexCandidates = getAffectedIndexCandidates(file);
final List<ID<?, ?>> affectedIndices = new ArrayList<ID<?, ?>>(affectedIndexCandidates.size());
Collection<ID<?, ?>> existingIndexedIds = IndexingStamp.getIndexedIds(file);
//noinspection ForLoopReplaceableByForEach
for (int i = 0, size = affectedIndexCandidates.size(); i < size; ++i) {
final ID<?, ?> indexId = affectedIndexCandidates.get(i);
try {
if (!needsFileContentLoading(indexId)) {
if (shouldUpdateIndex(file, indexId)) {
updateSingleIndex(indexId, file, null, true); // todo: set merge to false?
}
for(ID<?, ?> indexId:existingIndexedIds) {
if (myNotRequiringContentIndices.contains(indexId)) {
try {
updateSingleIndex(indexId, file, null, true);
} catch (StorageException e) {
LOG.info(e);
requestRebuild(indexId);
}
else { // the index requires file content
if (shouldUpdateIndex(file, indexId)) {
affectedIndices.add(indexId);
}
}
}
catch (StorageException e) {
LOG.info(e);
requestRebuild(indexId);
}
}
if (!affectedIndices.isEmpty()) {
if (markForReindex && !isTooLarge(file)) {
// only mark the file as unindexed, reindex will be done lazily
final Collection<ID<?, ?>> indexedIdsToUpdate = ContainerUtil.intersection(existingIndexedIds, myRequiringContentIndices);
if (markForReindex) {
// only mark the file as unindexed, reindex will be done lazily
if (!indexedIdsToUpdate.isEmpty()) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
FileType fileType = file.getFileType();
for (ID<?, ?> indexId : affectedIndices) {
ID id = IndexInfrastructure.getStubId(indexId, fileType);
IndexingStamp.update(file, id, IndexInfrastructure.INVALID_STAMP2);
}
}
});
// the file is for sure not a dir and it was previously indexed by at least one index
scheduleForUpdate(file);
}
else {
myFutureInvalidations.offer(new InvalidationTask(file) {
@Override
public void run() {
removeFileDataFromIndices(affectedIndices, file);
IndexingStamp.removeAllIndexedState(file);
}
});
}
// the file is for sure not a dir and it was previously indexed by at least one index
scheduleForUpdate(file);
}
if (!markForReindex) {
final boolean removedFromUpdateQueue = myFilesToUpdate.remove(file);// no need to update it anymore
if (removedFromUpdateQueue && affectedIndices.isEmpty()) {
// Currently the file is about to be deleted and previously it was scheduled for update and not processed up to now.
// Because the file was scheduled for update, at the moment of scheduling it was marked as unindexed,
// so, to be on the safe side, we have to schedule data invalidation from all content-requiring indices for this file
else {
myFilesToUpdate.remove(file);
if (!indexedIdsToUpdate.isEmpty()) {
myFutureInvalidations.offer(new InvalidationTask(file) {
@Override
public void run() {
List<ID<?, ?>> candidates = new ArrayList<ID<?, ?>>(affectedIndexCandidates);
candidates.retainAll(myRequiringContentIndices);
removeFileDataFromIndices(candidates, file);
removeFileDataFromIndices(indexedIdsToUpdate, file);
}
});
}
@@ -20,15 +20,19 @@ import com.intellij.openapi.vfs.InvalidVirtualFileAccessException;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.FileAttribute;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ConcurrentHashMap;
import com.intellij.util.io.DataInputOutputUtil;
import gnu.trove.TObjectLongHashMap;
import gnu.trove.TObjectLongProcedure;
import gnu.trove.TObjectProcedure;
import org.jetbrains.annotations.Nullable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.ArrayBlockingQueue;
/**
@@ -72,6 +76,10 @@ public class IndexingStamp {
}
}
private Timestamps() {
myIsDirty = true;
}
private void writeToStream(final DataOutputStream stream) throws IOException {
if (myIndexStamps != null && !myIndexStamps.isEmpty()) {
final long[] dominatingIndexStamp = new long[1];
@@ -194,6 +202,36 @@ public class IndexingStamp {
}
}
public static void removeAllIndexedState(VirtualFile file) {
synchronized (getStripedLock(file)) {
if (file instanceof NewVirtualFile && file.isValid()) {
myTimestampsCache.put(file, new Timestamps());
}
}
}
public static Collection<ID<?,?>> getIndexedIds(final VirtualFile file) {
synchronized (getStripedLock(file)) {
try {
Timestamps stamp = createOrGetTimeStamp(file);
if (stamp != null && stamp.myIndexStamps != null && !stamp.myIndexStamps.isEmpty()) {
final SmartList<ID<?, ?>> retained = new SmartList<ID<?, ?>>();
stamp.myIndexStamps.forEach(new TObjectProcedure<ID<?, ?>>() {
@Override
public boolean execute(ID<?, ?> object) {
retained.add(object);
return true;
}
});
return retained;
}
}
catch (InvalidVirtualFileAccessException ignored /*ok to ignore it here*/) {
}
}
return Collections.emptyList();
}
public static void flushCaches() {
flushCache(null);
myTimestampsCache.clear();
@@ -149,9 +149,7 @@ public abstract class FocusCommand extends ActiveRunnable implements Expirable {
@NotNull
public final ActionCallback run() {
if (myToFocus != null) {
if (!myToFocus.requestFocusInWindow()) {
myToFocus.requestFocus();
}
myToFocus.requestFocusInWindow();
}
clear();
return new ActionCallback.Done();
@@ -52,8 +52,10 @@ public class EditorChangeAction extends BasicUndoableAction {
long oldTimeStamp) {
super(document);
Charset charset = EncodingManager.getInstance().getEncoding(FileDocumentManager.getInstance().getFile(document), false);
myCharset = charset == null ? Charset.defaultCharset() : charset;
Charset charset = EncodingManager.getInstance().getEncoding(FileDocumentManager.getInstance().getFile(document), true);
if (charset == null) charset = EncodingManager.getInstance().getDefaultCharset();
if (charset == null) charset = Charset.defaultCharset();
myCharset = charset;
myOffset = offset;
myOldString = oldString == null ? "" : compressCharSequence(oldString, myCharset);
@@ -629,7 +629,7 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa
}
}
getFocusManager().requestFocus(myCancelButton, true);
myCancelButton.requestFocusInWindow();
}
}
});
@@ -19,10 +19,11 @@ import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.util.AsyncResult;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsBundle;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
@@ -142,7 +143,7 @@ public class RemoteFileInfoImpl implements RemoteContentProvider.DownloadingCall
VirtualFile localFile = new WriteAction<VirtualFile>() {
@Override
protected void run(final Result<VirtualFile> result) {
protected void run(@NotNull final Result<VirtualFile> result) {
final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(localIOFile);
if (file != null) {
file.refresh(false, false);
@@ -234,7 +235,7 @@ public class RemoteFileInfoImpl implements RemoteContentProvider.DownloadingCall
myCancelled.set(true);
if (myPrevLocalFile != null) {
myLocalVirtualFile = myPrevLocalFile;
myLocalFile = VfsUtil.virtualToIoFile(myLocalVirtualFile);
myLocalFile = VfsUtilCore.virtualToIoFile(myLocalVirtualFile);
myState = RemoteFileState.DOWNLOADED;
myErrorMessage = null;
}
@@ -291,4 +292,45 @@ public class RemoteFileInfoImpl implements RemoteContentProvider.DownloadingCall
}
}
}
@NotNull
@Override
public AsyncResult<VirtualFile> download() {
synchronized (myLock) {
switch (getState()) {
case DOWNLOADING_NOT_STARTED:
startDownloading();
return createDownloadedCallback(this);
case DOWNLOADING_IN_PROGRESS:
return createDownloadedCallback(this);
case DOWNLOADED:
return new AsyncResult.Done<VirtualFile>(myLocalVirtualFile);
case ERROR_OCCURRED:
default:
return new AsyncResult.Rejected<VirtualFile>();
}
}
}
private static AsyncResult<VirtualFile> createDownloadedCallback(@NotNull RemoteFileInfo remoteFileInfo) {
final AsyncResult<VirtualFile> callback = new AsyncResult<VirtualFile>();
remoteFileInfo.addDownloadingListener(new FileDownloadingAdapter() {
@Override
public void fileDownloaded(VirtualFile localFile) {
callback.setDone(localFile);
}
@Override
public void errorOccurred(@NotNull String errorMessage) {
callback.reject(errorMessage);
}
@Override
public void downloadingCancelled() {
callback.setRejected();
}
});
return callback;
}
}
@@ -27,6 +27,7 @@ import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileAttributes;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.LocalFileSystem;
@@ -207,6 +208,8 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
}
if (ensureCanonicalName) {
name = UriUtil.trimTrailingSlashes(UriUtil.trimLeadingSlashes(FileUtilRt.toSystemIndependentName(name)));
if (name.indexOf('/') != -1) return null; // name must not contain slashes in the middle
VirtualFile fake = new FakeVirtualFile(this, name);
name = delegate.getCanonicallyCasedName(fake);
if (name.isEmpty()) return null;
@@ -93,7 +93,7 @@ public final class WindowManagerImpl extends WindowManagerEx implements Applicat
}
private static final boolean ORACLE_BUG_8007219 = SystemInfo.isMac && SystemInfo.isJavaVersionAtLeast("1.7");
private static final int ORACLE_BUG_8007219_THRESHOLD = 10;
private static final int ORACLE_BUG_8007219_THRESHOLD = 5;
private Boolean myAlphaModeSupported = null;
@@ -557,25 +557,36 @@ public final class WindowManagerImpl extends WindowManagerEx implements Applicat
private void fixForOracleBug8007219(IdeFrameImpl frame) {
if ((myFrameExtendedState & Frame.MAXIMIZED_BOTH) > 0 && ORACLE_BUG_8007219) {
final Rectangle rect = ScreenUtil.getMainScreenBounds();
final Rectangle screenBounds = ScreenUtil.getMainScreenBounds();
final Insets screenInsets = ScreenUtil.getScreenInsets(frame.getGraphicsConfiguration());
final int leftGap = myFrameBounds.x - screenInsets.left;
myFrameBounds.x = myFrameBounds.x - screenInsets.left > ORACLE_BUG_8007219_THRESHOLD ?
myFrameBounds.x = leftGap > ORACLE_BUG_8007219_THRESHOLD ?
myFrameBounds.x :
screenInsets.left + ORACLE_BUG_8007219_THRESHOLD + 1;
myFrameBounds.y = myFrameBounds.y - screenInsets.top > ORACLE_BUG_8007219_THRESHOLD ?
final int topGap = myFrameBounds.y - screenInsets.top;
myFrameBounds.y = topGap > ORACLE_BUG_8007219_THRESHOLD ?
myFrameBounds.y :
screenInsets.top + ORACLE_BUG_8007219_THRESHOLD + 1;
myFrameBounds.width = rect.width - (myFrameBounds.width + myFrameBounds.x) > ORACLE_BUG_8007219_THRESHOLD ?
myFrameBounds.width :
rect.width - ORACLE_BUG_8007219_THRESHOLD - 1;
final int maximumFrameWidth = screenBounds.width - screenInsets.right - myFrameBounds.x;
myFrameBounds.height = rect.height - (myFrameBounds.height + myFrameBounds.y) > ORACLE_BUG_8007219_THRESHOLD ?
final int rightGap = maximumFrameWidth - myFrameBounds.width;
myFrameBounds.width = rightGap > ORACLE_BUG_8007219_THRESHOLD ?
myFrameBounds.width :
maximumFrameWidth - ORACLE_BUG_8007219_THRESHOLD - 1;
final int maximumFrameHeight = screenBounds.height - screenInsets.bottom - myFrameBounds.y;
final int bottomGap = maximumFrameHeight - myFrameBounds.height;
myFrameBounds.height = bottomGap > ORACLE_BUG_8007219_THRESHOLD ?
myFrameBounds.height :
rect.height - ORACLE_BUG_8007219_THRESHOLD - 1;
- ORACLE_BUG_8007219_THRESHOLD - 1;
}
}
@@ -475,7 +475,17 @@ public class VfsUtilTest extends PlatformLangTestCase {
assertNotNull(vDir.findChild("libFiles"));
assertNotNull(vDir.findChild("CssInvalidElement"));
VirtualFile ext = vDir.findChild("/extFiles/");
assertNotNull(ext);
assertNotNull(vDir.findChild("extFiles"));
assertNotNull(vDir.findChild("/extFiles/"));
assertNotNull(vDir.findChild("extFiles/"));
assertNotNull(vDir.findChild("/extFiles"));
assertNotNull(vDir.findChild("//extFiles"));
assertNotNull(vDir.findChild("extFiles///"));
assertNull(vDir.findChild("/xxx/extFiles/"));
assertNull(vDir.findChild("xxx/extFiles/"));
assertNull(vDir.findChild("/xxx/extFiles"));
assertNull(vDir.findChild("xxx/extFiles"));
assertNull(vDir.findChild("xxx//extFiles"));
}
}
@@ -0,0 +1,36 @@
package com.intellij.remoteServer.util;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.codeInsight.hint.HintUtil;
import com.intellij.icons.AllIcons;
import com.intellij.ui.HyperlinkAdapter;
import com.intellij.ui.HyperlinkLabel;
import com.intellij.ui.awt.RelativePoint;
import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
/**
* @author michael.golubev
*/
public class TooltipUtil {
public static HyperlinkLabel createTooltip(final String message) {
final HyperlinkLabel link = new HyperlinkLabel("");
link.setIcon(AllIcons.General.Help_small);
link.setUseIconAsLink(true);
link.setIconTextGap(0);
link.addHyperlinkListener(new HyperlinkAdapter() {
@Override
protected void hyperlinkActivated(HyperlinkEvent e) {
final JLabel label = new JLabel(message);
label.setBorder(HintUtil.createHintBorder());
label.setBackground(HintUtil.INFORMATION_COLOR);
label.setOpaque(true);
HintManager.getInstance()
.showHint(label, RelativePoint.getSouthEastOf(link), HintManager.HIDE_BY_ANY_KEY | HintManager.HIDE_BY_TEXT_CHANGE, -1);
}
});
return link;
}
}
@@ -1,33 +1,17 @@
/*
* Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved.
* Copyright 2000-2013 JetBrains s.r.o.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 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
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduct the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the distribution.
*
* Neither the name of JetBrains or IntelliJ IDEA
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT
* BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT
* OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN
* IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* 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.psi.formatter;
@@ -38,6 +22,7 @@ import com.intellij.mock.MockProgressIndicator;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.command.impl.UndoManagerImpl;
import com.intellij.openapi.command.undo.UndoManager;
import com.intellij.openapi.editor.Document;
@@ -206,38 +191,34 @@ public abstract class FormatterTestCase extends LightPlatformTestCase {
editor = null;
}
CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
WriteCommandAction.runWriteCommandAction(getProject(), new Runnable() {
@Override
public void run() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
document.replaceString(0, document.getTextLength(), text);
PsiDocumentManager.getInstance(getProject()).commitDocument(document);
assertEquals(file.getText(), document.getText());
if (false && doCheckDocumentUpdate()) {
makeFolding(file, editor);
}
try {
if (doReformatRangeTest) {
CodeStyleManager.getInstance(getProject()).reformatRange(file, file.getTextRange().getStartOffset(), file.getTextRange().getEndOffset());
} else if (myTextRange != null) {
CodeStyleManager.getInstance(getProject()).reformatText(file, myTextRange.getStartOffset(), myTextRange.getEndOffset());
}
else {
CodeStyleManager.getInstance(getProject())
.reformatText(file, file.getTextRange().getStartOffset(), file.getTextRange().getEndOffset());
}
}
catch (IncorrectOperationException e) {
fail();
}
document.replaceString(0, document.getTextLength(), text);
PsiDocumentManager.getInstance(getProject()).commitDocument(document);
assertEquals(file.getText(), document.getText());
if (false && doCheckDocumentUpdate()) {
makeFolding(file, editor);
}
try {
if (doReformatRangeTest) {
CodeStyleManager.getInstance(getProject())
.reformatRange(file, file.getTextRange().getStartOffset(), file.getTextRange().getEndOffset());
}
});
else if (myTextRange != null) {
CodeStyleManager.getInstance(getProject()).reformatText(file, myTextRange.getStartOffset(), myTextRange.getEndOffset());
}
else {
CodeStyleManager.getInstance(getProject())
.reformatText(file, file.getTextRange().getStartOffset(), file.getTextRange().getEndOffset());
}
}
catch (IncorrectOperationException e) {
fail();
}
}
}, "", "");
});
assertEquals(textAfter, document.getText());
PsiDocumentManager.getInstance(getProject()).commitDocument(document);
@@ -33,9 +33,7 @@ public class ClassUtilCore {
clearMap(jarFileFactory.getDeclaredField(FILE_CACHE));
clearMap(jarFileFactory.getDeclaredField(URL_CACHE));
}
catch (Exception e) {
System.out.println("Failed to clear URL cache");
e.printStackTrace();
catch (Exception ignore) {
// Do nothing.
}
}
@@ -37,14 +37,16 @@ public class FrequentEventDetector {
public void eventHappened() {
if (myEventsPosted.incrementAndGet() > myEventCountThreshold) {
synchronized (myEventsPosted) {
boolean shouldLog = false;
if (myEventsPosted.get() > myEventCountThreshold) {
long timeNow = System.currentTimeMillis();
if (timeNow - myStartedCounting < myTimeSpanMs) {
LOG.info("Too many events posted\n" + ExceptionUtil.getThrowableText(new Throwable()));
}
shouldLog = timeNow - myStartedCounting < myTimeSpanMs;
myEventsPosted.set(0);
myStartedCounting = timeNow;
}
if (shouldLog) {
LOG.info("Too many events posted\n" + ExceptionUtil.getThrowableText(new Throwable()));
}
}
}
@@ -21,6 +21,7 @@ import com.intellij.openapi.util.Clock;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.mac.foundation.Foundation;
import com.intellij.ui.mac.foundation.ID;
import com.intellij.util.EnvironmentUtil;
import org.jetbrains.annotations.NotNull;
import java.text.DateFormat;
@@ -275,6 +276,15 @@ public class DateFormatUtil {
}
}
if (SystemInfo.isUnix && !SystemInfo.isMac) {
try {
result = getUnixTimeFormat(format, type);
}
catch (Throwable t) {
LOG.error(t);
}
}
if (result == null) {
switch (type) {
case TIME:
@@ -385,4 +395,35 @@ public class DateFormatUtil {
Foundation.invoke(autoReleasePool, Foundation.createSelector("release"));
}
}
private static DateFormat getUnixTimeFormat(int format, DateType type) {
String localeStr = EnvironmentUtil.getValue("LC_TIME");
if (localeStr == null) return null;
localeStr = localeStr.trim();
int p = localeStr.indexOf('.');
if (p > 0) localeStr = localeStr.substring(0, p);
p = localeStr.indexOf('@');
if (p > 0) localeStr = localeStr.substring(0, p);
Locale locale;
p = localeStr.indexOf('_');
if (p < 0) {
locale = new Locale(localeStr);
}
else {
locale = new Locale(localeStr.substring(0, p), localeStr.substring(p + 1));
}
switch (type) {
case TIME:
return DateFormat.getTimeInstance(format, locale);
case DATE:
return DateFormat.getDateInstance(format, locale);
case DATETIME:
return DateFormat.getDateTimeInstance(format, format, locale);
}
return null;
}
}
@@ -15,21 +15,28 @@
*/
package com.intellij.util.text;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.util.Clock;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtil;
import org.junit.Test;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class DateFormatUtilTest {
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy hh.mm.ss");
@SuppressWarnings("SpellCheckingInspection") private static final DateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy hh.mm.ss");
@Test
public void testBasics() throws ParseException {
@@ -43,36 +50,34 @@ public class DateFormatUtilTest {
}
@Test
public void testTime() throws ParseException {
public void testTime() throws Exception {
Clock.setTime(2004, 11, 10, 17, 10, 15);
if (SystemInfo.isMac) {
assertEquals("17:10", DateFormatUtil.formatTime(Clock.getTime()));
assertEquals("17:10:15", DateFormatUtil.formatTimeWithSeconds(Clock.getTime()));
assertEquals("17:10:15", DateFormatUtil.formatTimeWithSeconds(new Date(Clock.getTime())));
}
else if (SystemInfo.isUnix) {
assertEquals("5:10:15 PM", printTimeForLocale("en_US.UTF-8"));
assertEquals("17:10:15", printTimeForLocale("de_DE.UTF-8"));
}
else {
assertEquals(DateFormat.getTimeInstance(DateFormat.SHORT).format(Clock.getTime()),
DateFormatUtil.formatTime(Clock.getTime()));
assertEquals(DateFormat.getTimeInstance(DateFormat.MEDIUM).format(Clock.getTime()),
DateFormatUtil.formatTimeWithSeconds(Clock.getTime()));
DateFormatUtil.formatTimeWithSeconds(new Date(Clock.getTime())));
}
}
@Test
public void testPrettyDateTime() throws ParseException {
Clock.setTime(2004, 11, 10, 17, 0);
doTestDateTime("Moments ago", "10.12.2004 16.59.31");
doTestDateTime("A minute ago", "10.12.2004 16.59.29");
doTestDateTime("5 minutes ago", "10.12.2004 16.55.00");
doTestDateTime("1 hour ago", "10.12.2004 16.00.00");
doTestDateTime("Today " + DateFormatUtil.formatTime(DATE_FORMAT.parse("10.12.2004 15.55.00")), "10.12.2004 15.55.00");
doTestDateTime("Yesterday " + DateFormatUtil.formatTime(DATE_FORMAT.parse("09.12.2004 15.00.00")), "09.12.2004 15.00.00");
doTestDateTime(DateFormatUtil.formatDateTime(DATE_FORMAT.parse("08.12.2004 15.00.00")), "08.12.2004 15.00.00");
doTestDateTime(DateFormatUtil.formatDateTime(DATE_FORMAT.parse("07.12.2004 15.00.00")), "07.12.2004 15.00.00");
doTestDateTime("Today " + DateFormatUtil.formatTime(DATE_FORMAT.parse("10.12.2004 19.00.00")), "10.12.2004 19.00.00");
Clock.setTime(2004, 0, 1, 15, 53);
@@ -80,6 +85,18 @@ public class DateFormatUtilTest {
doTestDateTime("Yesterday " + DateFormatUtil.formatTime(DATE_FORMAT.parse("31.12.2003 15.00.00")), "31.12.2003 15.00.00");
}
@Test
public void testAboutDialogDataFormatter() {
assertEquals("December 12, 2012", DateFormatUtil.formatAboutDialogDate(date(2012, 12, 12, 15, 35, 12)));
assertEquals("January 1, 1999", DateFormatUtil.formatAboutDialogDate(date(1999, 1, 1, 0, 0, 0)));
}
@Test
public void testFormatFrequency() {
assertEquals("Once in 2 minutes", DateFormatUtil.formatFrequency(2 * 60 * 1000));
assertEquals("Once in a few moments", DateFormatUtil.formatFrequency(1000));
}
private static void doTestPrettyDate(String expected, String date) throws ParseException {
assertEquals(expected, DateFormatUtil.formatPrettyDate(DATE_FORMAT.parse(date)));
}
@@ -92,158 +109,26 @@ public class DateFormatUtilTest {
return new GregorianCalendar(year, month - 1, day, hour, minute, second).getTime();
}
@Test
public void testConvertingMacToJavaPattern() throws Throwable {
Clock.setTime(date(2004, 2, 5, 16, 6, 7).getTime() + 8);
private static String printTimeForLocale(String locale) throws IOException {
List<String> classpath = ContainerUtil.newArrayList();
classpath.addAll(PathManager.getUtilClassPath());
classpath.add(PathManager.getJarPathForClass(PrintTime.class));
ProcessBuilder builder = new ProcessBuilder()
.command(System.getProperty("java.home") + "/bin/java",
"-classpath",
StringUtil.join(classpath, File.pathSeparator),
PrintTime.class.getName(),
String.valueOf(Clock.getTime()))
.redirectErrorStream(true);
builder.environment().put("LC_TIME", locale);
Process process = builder.start();
String mon = new SimpleDateFormat("MMM").format(Clock.getTime());
String month = new SimpleDateFormat("MMMMM").format(Clock.getTime());
String weekd = new SimpleDateFormat("EEE").format(Clock.getTime());
String weekday = new SimpleDateFormat("EEEEE").format(Clock.getTime());
assertConvertedFormat("%y %Y", "04 2004");
assertConvertedFormat("%b %B %m", mon + " " + month + " 02");
assertConvertedFormat("%d %e %j", "05 5 036");
assertConvertedFormat("%a %A %w", weekd + " " + weekday + " " + weekd);
assertConvertedFormat("%H %I", "16 04");
assertConvertedFormat("%M %S %F %p", "06 07 008 PM");
assertConvertedFormatMatches("%z %Z", "\\+\\d{4} \\w{3}");
assertConvertedFormat(" foo bar ", " foo bar ");
assertConvertedFormat(" 'foo''a'a'' '' ' ", " 'foo''a'a'' '' ' ");
assertConvertedFormat(" '%a''%a'%a'' '' ' '%a ", " '" + weekd + "''" + weekd + "'" + weekd + "'' '' ' '" + weekd + " ");
assertConvertedFormat("'a'", "'a'");
assertConvertedFormat("'", "'");
assertConvertedFormat("''", "''");
assertConvertedFormat("a", "a");
assertConvertedFormat(" ", " ");
assertConvertedFormat("%1", "?%1?");
assertConvertedFormat("", "");
assertConvertedFormat("%", "");
}
private static void assertConvertedFormat(String pattern, String expected) throws Throwable {
String converted = convertMacPattern(pattern);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
try {
assertEquals(expected, new SimpleDateFormat(converted).format(Clock.getTime()));
return reader.readLine();
}
catch (Throwable e) {
System.out.println("cannot format with [" + converted + "]");
throw e;
finally {
reader.close();
}
}
private static void assertConvertedFormatMatches(String pattern, String expectedPattern) throws Throwable {
String converted = convertMacPattern(pattern);
try {
String actual = new SimpleDateFormat(converted).format(Clock.getTime());
assertTrue(actual, actual.matches(expectedPattern));
}
catch (Throwable e) {
System.out.println("cannot format with [" + converted + "]");
throw e;
}
}
private static String convertMacPattern(String macPattern) {
StringBuilder b = new StringBuilder();
boolean isSpecial = false;
boolean isText = false;
for (int i = 0; i < macPattern.length(); i++) {
char c = macPattern.charAt(i);
if (isSpecial) {
String replacement = null;
if (c == '%') replacement = "$";
// year
if (c == 'y') replacement = "yy";
if (c == 'Y') replacement = "yyyy";
// month
if (c == 'm') replacement = "MM";
if (c == 'b') replacement = "MMM";
if (c == 'B') replacement = "MMMMM";
// day on month
if (c == 'e') replacement = "d";
if (c == 'd') replacement = "dd";
// day of year
if (c == 'j') replacement = "DDD";
// day of week
if (c == 'w') replacement = "E"; // SimpleDateFormat doesn't support formatting weekday as a number
if (c == 'a') replacement = "EEE";
if (c == 'A') replacement = "EEEEE";
// hours
if (c == 'H') replacement = "HH"; // 0-24
//if (c == 'H') replacement = "k"; // 1-24
//if (c == 'I') replacement = "K"; // 0-11
if (c == 'I') replacement = "hh"; // 1-12
//minute
if (c == 'M') replacement = "mm";
//second
if (c == 'S') replacement = "ss";
//millisecond
if (c == 'F') replacement = "SSS";
//millisecond
if (c == 'p') replacement = "a";
//millisecond
if (c == 'Z') replacement = "zzz";
//millisecond
if (c == 'z') replacement = "Z";
//todo if (c == 'c') replacement = "MMMMM";, x, X
if (replacement == null) replacement = "'?%" + c + "?'";
b.append(replacement);
isSpecial = false;
}
else {
isSpecial = c == '%';
if (isSpecial) {
isText = false;
}
else {
if (isText) {
if (c == '\'' || Character.isWhitespace(c)) b.append('\'');
isText = !Character.isWhitespace(c);
}
else {
if (c == '\'' || !Character.isWhitespace(c)) b.append('\'');
isText = !Character.isWhitespace(c) && c != '\'';
}
b.append(c);
if (isText && i == macPattern.length() - 1) b.append('\'');
}
}
}
return b.toString();
}
@Test
public void testAboutDialogDataFormatter() {
assertEquals("December 12, 2012",
DateFormatUtil.formatAboutDialogDate(date(2012, 12, 12, 15, 35, 12)));
assertEquals("January 1, 1999",
DateFormatUtil.formatAboutDialogDate(date(1999, 1, 1, 0, 0, 0)));
}
@Test
public void testFormatFrequency() {
assertEquals("Once in 2 minutes",
DateFormatUtil.formatFrequency(2 * 60 * 1000));
assertEquals("Once in a few moments",
DateFormatUtil.formatFrequency(1000));
}
}
@@ -0,0 +1,28 @@
/*
* Copyright 2000-2013 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.util.text;
public class PrintTime {
public static void main(String[] args) {
if (args.length != 1) {
throw new IllegalArgumentException("Time expected");
}
long time = Long.parseLong(args[0]);
String result = DateFormatUtil.formatTimeWithSeconds(time);
System.out.println(result);
}
}
@@ -1386,7 +1386,7 @@
groupBundle="messages.InspectionsBundle" groupKey="group.names.junit.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.junit.MisspelledTearDownInspection"/>
<localInspection language="JAVA" suppressId="MisorderedAssertEqualsArguments" alternativeId="MisorderedAssertEqualsArguments" shortName="MisorderedAssertEqualsParameters"
bundle="com.siyeh.InspectionGadgetsBundle" key="misordered.assert.equals.parameters.display.name"
bundle="com.siyeh.InspectionGadgetsBundle" key="misordered.assert.equals.arguments.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.junit.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.junit.MisorderedAssertEqualsParametersInspection"/>
<localInspection language="JAVA" shortName="MultipleExceptionsDeclaredOnTestMethod" bundle="com.siyeh.InspectionGadgetsBundle"
@@ -731,7 +731,7 @@ implicit.numeric.conversion.display.name=Implicit numeric conversion
unnecessary.interface.modifier.display.name=Unnecessary interface modifier
confusing.main.method.display.name=Confusing 'main()' method
octal.literal.display.name=Octal integer
misordered.assert.equals.parameters.display.name=Misordered 'assertEquals()' arguments
misordered.assert.equals.arguments.display.name=Misordered 'assertEquals()' arguments
unnecessary.constructor.display.name=Redundant no-arg constructor
method.name.same.as.parent.name.display.name=Method name same as parent class name
java.lang.reflect.display.name=Use of 'java.lang.reflect'
@@ -1073,7 +1073,7 @@ asserts.without.messages.problem.descriptor=JUnit <code>#ref()</code> without me
test.case.with.constructor.problem.descriptor=Initialization logic in constructor <code>#ref()</code> instead of 'setUp()' #loc
test.case.with.constructor.problem.descriptor.initializer=Initialization logic in initializer instead of 'setUp()'
misspelled.set.up.problem.descriptor=<code>#ref()</code> probably be 'setUp()' #loc
misordered.assert.equals.parameters.problem.descriptor=Arguments to <code>#ref()</code> in wrong order #loc
misordered.assert.equals.arguments.problem.descriptor=Arguments to <code>#ref()</code> in wrong order #loc
misspelled.tear.down.problem.descriptor=<code>#ref()</code> method should probably be 'tearDown()' #loc
static.suite.problem.descriptor=JUnit <code>#ref()</code> methods not declared 'static' #loc
setup.calls.super.setup.problem.descriptor=<code>#ref()</code> does not call 'super.setUp()' #loc
@@ -1196,7 +1196,7 @@ if.statement.with.identical.branches.collapse.quickfix=Collapse 'if' statement
foreach.replace.quickfix=Replace with 'foreach'
unnecessary.boxing.remove.quickfix=Remove boxing
unnecessary.unboxing.remove.quickfix=Remove unboxing
misordered.assert.equals.parameters.flip.quickfix=Flip compared arguments
misordered.assert.equals.arguments.flip.quickfix=Flip compared arguments
setup.calls.super.setup.add.quickfix=Add call to 'super.setUp()'
simplify.junit.assertion.simplify.quickfix=Simplify assertion
teardown.calls.super.teardown.add.quickfix=Add call to 'super.tearDown()'
@@ -1944,7 +1944,7 @@ class.only.used.in.one.package.display.name=Class only used from one other packa
class.only.used.in.one.package.problem.descriptor=Class <code>#ref</code> has only dependencies on and/or dependents in package ''{0}'' #loc
unnecessary.return.option=Ignore in then branch of 'if' statement with 'else' branch
usage.of.obsolete.assert.display.name=Usage of obsolete 'junit.framework.Assert'
use.of.obsolete.assert.problem.descriptor=Call to <code>#ref()</code> from 'org.junit.framework.Assert' should be replaced with call to method from 'org.junit.Assert' #loc
use.of.obsolete.assert.problem.descriptor=Call to <code>#ref()</code> from 'junit.framework.Assert' should be replaced with call to method from 'org.junit.Assert' #loc
use.of.obsolete.assert.quickfix=Replace with 'org.junit.Assert' method call
properties.object.as.hashtable.set.quickfix=Replace with call to 'setProperty()'
properties.object.as.hashtable.get.quickfix=Replace with call to 'getProperty()'
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -59,11 +59,6 @@ public class PrivateMemberAccessBetweenOuterAndInnerClassInspection
final PsiMember member = (PsiMember)infos[1];
@NonNls final String memberName;
if (member instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)member;
if (method.isConstructor()) {
}
memberName = member.getName() + "()";
}
else {
@@ -168,10 +163,10 @@ public class PrivateMemberAccessBetweenOuterAndInnerClassInspection
@Override
public BaseInspectionVisitor buildVisitor() {
return new PrivateMemberAccessFromInnerClassVisior();
return new PrivateMemberAccessFromInnerClassVisitor();
}
private static class PrivateMemberAccessFromInnerClassVisior
private static class PrivateMemberAccessFromInnerClassVisitor
extends BaseInspectionVisitor {
@Override
@@ -225,9 +220,6 @@ public class PrivateMemberAccessBetweenOuterAndInnerClassInspection
return;
}
super.visitReferenceExpression(expression);
if (expression.getQualifierExpression() == null) {
return;
}
final PsiElement referenceNameElement =
expression.getReferenceNameElement();
if (referenceNameElement == null) {
@@ -246,12 +238,9 @@ public class PrivateMemberAccessBetweenOuterAndInnerClassInspection
if (!member.hasModifierProperty(PsiModifier.PRIVATE)) {
return;
}
final PsiClass memberClass =
ClassUtils.getContainingClass(member);
if (memberClass == null) {
return;
}
if (memberClass.equals(containingClass)) {
final PsiClass memberClass = ClassUtils.getContainingClass(member);
if (memberClass == null || memberClass.equals(containingClass) ||
(!PsiTreeUtil.isAncestor(containingClass, memberClass, true) && !PsiTreeUtil.isAncestor(memberClass, containingClass, true))) {
return;
}
registerError(referenceNameElement, memberClass, member);
@@ -259,14 +248,11 @@ public class PrivateMemberAccessBetweenOuterAndInnerClassInspection
@Nullable
private static PsiClass getContainingContextClass(PsiElement element) {
final PsiClass aClass =
ClassUtils.getContainingClass(element);
final PsiClass aClass = ClassUtils.getContainingClass(element);
if (aClass instanceof PsiAnonymousClass) {
final PsiAnonymousClass anonymousClass =
(PsiAnonymousClass)aClass;
final PsiExpressionList args = anonymousClass.getArgumentList();
if (args != null &&
PsiTreeUtil.isAncestor(args, element, true)) {
final PsiAnonymousClass anonymousClass = (PsiAnonymousClass)aClass;
final PsiExpressionList arguments = anonymousClass.getArgumentList();
if (arguments != null && PsiTreeUtil.isAncestor(arguments, element, true)) {
return ClassUtils.getContainingClass(aClass);
}
}
@@ -0,0 +1,193 @@
/*
* Copyright 2000-2013 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.siyeh.ig.junit;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
/**
* @author Bas Leijdekkers
*/
public abstract class MisorderedAssertEqualsArgumentsInspectionBase extends BaseInspection {
@NonNls
private static final Set<String> methodNames =
ContainerUtil.newHashSet("assertEquals", "assertEqualsNoOrder", "assertNotEquals", "assertArrayEquals", "assertSame",
"assertNotSame", "failNotSame", "failNotEquals");
public abstract boolean checkTestNG();
@Override
@NotNull
public final String getDisplayName() {
return InspectionGadgetsBundle.message("misordered.assert.equals.arguments.display.name");
}
@Override
@NotNull
protected final String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message("misordered.assert.equals.arguments.problem.descriptor");
}
@Override
public final InspectionGadgetsFix buildFix(Object... infos) {
return new FlipArgumentsFix();
}
private static class FlipArgumentsFix extends InspectionGadgetsFix {
@Override
@NotNull
public String getFamilyName() {
return getName();
}
@Override
@NotNull
public String getName() {
return InspectionGadgetsBundle.message("misordered.assert.equals.arguments.flip.quickfix");
}
@Override
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement methodNameIdentifier = descriptor.getPsiElement();
final PsiElement parent = methodNameIdentifier.getParent();
if (parent == null) {
return;
}
final PsiMethodCallExpression callExpression = (PsiMethodCallExpression)parent.getParent();
if (callExpression == null) {
return;
}
final PsiReferenceExpression methodExpression = callExpression.getMethodExpression();
final PsiMethod method = (PsiMethod)methodExpression.resolve();
if (method == null) {
return;
}
final PsiClass containingClass = method.getContainingClass();
final boolean junit;
if (InheritanceUtil.isInheritor(containingClass, "org.testng.Assert")) {
junit = false;
}
else if (InheritanceUtil.isInheritor(containingClass, "org.testng.AssertJUnit") ||
InheritanceUtil.isInheritor(containingClass, "junit.framework.Assert") ||
InheritanceUtil.isInheritor(containingClass, "org.junit.Assert")) {
junit = true;
}
else {
return;
}
final PsiParameterList parameterList = method.getParameterList();
final PsiParameter[] parameters = parameterList.getParameters();
final PsiType stringType = TypeUtils.getStringType(callExpression);
final PsiType parameterType1 = parameters[0].getType();
final PsiExpressionList argumentList = callExpression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
final PsiExpression expectedArgument;
final PsiExpression actualArgument;
if (junit) {
if (parameterType1.equals(stringType) && parameters.length > 2) {
expectedArgument = arguments[1];
actualArgument = arguments[2];
}
else {
expectedArgument = arguments[0];
actualArgument = arguments[1];
}
}
else {
actualArgument = arguments[0];
expectedArgument = arguments[1];
}
final PsiElement copy = expectedArgument.copy();
expectedArgument.replace(actualArgument);
actualArgument.replace(copy);
}
}
@Override
public final BaseInspectionVisitor buildVisitor() {
return new MisorderedAssertEqualsParametersVisitor();
}
private class MisorderedAssertEqualsParametersVisitor extends BaseInspectionVisitor {
@Override
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression);
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
@NonNls final String methodName = methodExpression.getReferenceName();
if (!methodNames.contains(methodName)) {
return;
}
final PsiMethod method = expression.resolveMethod();
if (method == null || method.hasModifierProperty(PsiModifier.PRIVATE)) {
return;
}
final PsiExpressionList argumentList = expression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
if (arguments.length < 2) {
return;
}
final PsiType stringType = TypeUtils.getStringType(expression);
final PsiClass containingClass = method.getContainingClass();
final PsiExpression expectedArgument;
final PsiExpression actualArgument;
if (checkTestNG() ?
InheritanceUtil.isInheritor(containingClass, "org.testng.AssertJUnit") :
InheritanceUtil.isInheritor(containingClass, "junit.framework.Assert") ||
InheritanceUtil.isInheritor(containingClass, "org.junit.Assert")) {
final PsiType firstArgumentType = arguments[0].getType();
if (stringType.equals(firstArgumentType) && arguments.length > 2) {
expectedArgument = arguments[1];
actualArgument = arguments[2];
}
else {
expectedArgument = arguments[0];
actualArgument = arguments[1];
}
} else if (checkTestNG() && InheritanceUtil.isInheritor(containingClass, "org.testng.Assert")){
expectedArgument = arguments[1];
actualArgument = arguments[0];
} else {
return;
}
if (expectedArgument == null || actualArgument == null) {
return;
}
if (ExpressionUtils.computeConstantExpression(expectedArgument) != null) {
return;
}
if (ExpressionUtils.computeConstantExpression(actualArgument) == null) {
return;
}
registerMethodCallError(expression);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2012 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,21 +15,9 @@
*/
package com.siyeh.ig.junit;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class MisorderedAssertEqualsParametersInspection extends BaseInspection {
public class MisorderedAssertEqualsParametersInspection extends MisorderedAssertEqualsArgumentsInspectionBase {
@Nullable
@Override
@@ -38,148 +26,7 @@ public class MisorderedAssertEqualsParametersInspection extends BaseInspection {
}
@Override
@NotNull
public String getDisplayName() {
return InspectionGadgetsBundle.message("misordered.assert.equals.parameters.display.name");
}
@Override
@NotNull
protected String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message("misordered.assert.equals.parameters.problem.descriptor");
}
@Override
public InspectionGadgetsFix buildFix(Object... infos) {
return new FlipParametersFix();
}
private static class FlipParametersFix extends InspectionGadgetsFix {
@Override
@NotNull
public String getFamilyName() {
return getName();
}
@Override
@NotNull
public String getName() {
return InspectionGadgetsBundle.message("misordered.assert.equals.parameters.flip.quickfix");
}
@Override
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement methodNameIdentifier = descriptor.getPsiElement();
final PsiElement parent = methodNameIdentifier.getParent();
assert parent != null;
final PsiMethodCallExpression callExpression = (PsiMethodCallExpression)parent.getParent();
assert callExpression != null;
final PsiReferenceExpression methodExpression = callExpression.getMethodExpression();
final PsiMethod method = (PsiMethod)methodExpression.resolve();
assert method != null;
final PsiParameterList parameterList = method.getParameterList();
final PsiParameter[] parameters = parameterList.getParameters();
final PsiType stringType = TypeUtils.getStringType(callExpression);
final PsiType parameterType1 = parameters[0].getType();
final PsiExpressionList argumentList = callExpression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
final PsiExpression actualArgument;
final PsiExpression expectedArgument;
if (parameterType1.equals(stringType) && parameters.length > 2) {
expectedArgument = arguments[1];
actualArgument = arguments[2];
}
else {
expectedArgument = arguments[0];
actualArgument = arguments[1];
}
final String actualArgumentText = actualArgument.getText();
final String expectedArgumentText = expectedArgument.getText();
replaceExpression(expectedArgument, actualArgumentText);
replaceExpression(actualArgument, expectedArgumentText);
}
}
@Override
public BaseInspectionVisitor buildVisitor() {
return new MisorderedAssertEqualsParametersVisitor();
}
private static class MisorderedAssertEqualsParametersVisitor extends BaseInspectionVisitor {
@Override
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression);
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
@NonNls final String methodName = methodExpression.getReferenceName();
if (!"assertEquals".equals(methodName) && !"assertArrayEquals".equals(methodName)) {
return;
}
final PsiMethod method = expression.resolveMethod();
if (method == null) {
return;
}
final PsiClass containingClass = method.getContainingClass();
if (!InheritanceUtil.isInheritor(containingClass, "junit.framework.Assert") &&
!InheritanceUtil.isInheritor(containingClass, "org.junit.Assert")) {
return;
}
final PsiExpressionList argumentList = expression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
if (arguments.length < 2) {
return;
}
final PsiType stringType = TypeUtils.getStringType(expression);
final PsiType argumentType1 = arguments[0].getType();
final PsiExpression expectedArgument;
final PsiExpression actualArgument;
if (stringType.equals(argumentType1) && arguments.length > 2) {
expectedArgument = arguments[1];
actualArgument = arguments[2];
}
else {
expectedArgument = arguments[0];
actualArgument = arguments[1];
}
if (expectedArgument == null || actualArgument == null) {
return;
}
if (isLiteralOrConstant(expectedArgument)) {
return;
}
if (!isLiteralOrConstant(actualArgument)) {
return;
}
registerMethodCallError(expression);
}
private static boolean isLiteralOrConstant(PsiExpression expression) {
if (expression instanceof PsiLiteralExpression) {
return true;
}
else if (expression instanceof PsiNewExpression) {
final PsiNewExpression newExpression = (PsiNewExpression)expression;
final PsiExpressionList argumentList = newExpression.getArgumentList();
if (argumentList == null) {
return true;
}
for (PsiExpression argument : argumentList.getExpressions()) {
if (!isLiteralOrConstant(argument)) {
return false;
}
}
return true;
}
if (!(expression instanceof PsiReferenceExpression)) {
return false;
}
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression;
final PsiElement target = referenceExpression.resolve();
if (!(target instanceof PsiField)) {
return false;
}
final PsiField field = (PsiField)target;
return field.hasModifierProperty(PsiModifier.STATIC) && field.hasModifierProperty(PsiModifier.FINAL);
}
public boolean checkTestNG() {
return false;
}
}
@@ -1,7 +1,7 @@
<html>
<body>
Reports any uses to <b>javax.sql.DriverManager</b>
to acquire a JDBC connection. The <b>javax.sql.DriverManager</b>
Reports any uses to <b>java.sql.DriverManager</b>
to acquire a JDBC connection. The <b>java.sql.DriverManager</b>
has been superseded by <b>javax.sql.Datasource</b>, which
allows for connection pooling and other optimizations.
<!-- tooltip end -->
@@ -1,16 +0,0 @@
package com.siyeh.igtest.j2me;
import java.awt.*;
public class PrivateMemberAccessBetweenOuterAndInnerClass {
private String caption = "Button";
private void initialize() {
Button btn = new Button(caption) {
public void foo() {
System.out.println(caption);
}
};
}
}
@@ -0,0 +1,14 @@
package com.siyeh.igtest.j2me.private_member_access_between_outer_and_inner_class;
public class PrivateMemberAccessBetweenOuterAndInnerClass {
private String caption = "Button";
private void initialize() {
System.out.println(caption);
Object btn = new Object() {
public void foo() {
System.out.println(<warning descr="Access to private member of class 'PrivateMemberAccessBetweenOuterAndInnerClass'">caption</warning>);
}
};
}
}
@@ -0,0 +1,21 @@
package com.siyeh.igtest.j2me.private_member_access_between_outer_and_inner_class;
public class Simple {
private int i;
private Simple() {}
private void foo() {}
class Inner {{
new <warning descr="Access to private member of class 'Simple'">Simple</warning>();
System.out.println(<warning descr="Access to private member of class 'Simple'">i</warning>);
<warning descr="Access to private member of class 'Simple'">foo</warning>();
}}
}
class Other {
void foo(Simple o) {
System.out.println(o.<error descr="'i' has private access in 'com.siyeh.igtest.j2me.private_member_access_between_outer_and_inner_class.Simple'">i</error>);
}
}
@@ -0,0 +1,16 @@
import org.junit.Assert;
class Simple {
public static final int EXPECTED = -9;
private class BeanCreator {
public BeanCreator withQuery(int s) {
Assert.<warning descr="Arguments to 'assertEquals()' in wrong order">assertEquals</warning>(s, -1);
Assert.<warning descr="Arguments to 'assertSame()' in wrong order">assertSame</warning>(s, EXPECTED);
junit.framework.Assert.<warning descr="Arguments to 'failNotEquals()' in wrong order">failNotEquals</warning>("asdfasd", s, EXPECTED);
return null;
}
}
}
@@ -0,0 +1,8 @@
package com.siyeh.igtest.junit.use_of_obsolete_assert;
public class ObsoleteAssert {
public void testMe(int s) {
junit.framework.Assert.<warning descr="Call to 'assertEquals()' from 'junit.framework.Assert' should be replaced with call to method from 'org.junit.Assert'">assertEquals</warning>("asdfasd", -1, s);
}
}
@@ -0,0 +1,33 @@
/*
* Copyright 2000-2013 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.siyeh.ig.j2me;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.siyeh.ig.LightInspectionTestCase;
/**
* @author Bas Leijdekkers
*/
public class PrivateMemberAccessBetweenOuterAndInnerClassInspectionTest extends LightInspectionTestCase {
public void testSimple() { doTest(); }
public void testPrivateMemberAccessBetweenOuterAndInnerClass() { doTest(); }
@Override
protected InspectionProfileEntry getInspection() {
return new PrivateMemberAccessBetweenOuterAndInnerClassInspection();
}
}
@@ -0,0 +1,47 @@
/*
* Copyright 2000-2013 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.siyeh.ig.junit;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.siyeh.ig.LightInspectionTestCase;
/**
* @author Bas Leijdekkers
*/
public class MisorderedAssertEqualsParametersInspectionTest extends LightInspectionTestCase {
public void testSimple() { doTest(); }
@Override
protected String[] getEnvironmentClasses() {
return new String[] {
"package org.junit;" +
"public class Assert {" +
" static public void assertEquals(long expected, long actual) {}" +
" static public void assertSame(Object expected, Object actual) {}" +
"}",
"package junit.framework;" +
"public class Assert {" +
" static public void failNotEquals(String message, Object expected, Object actual) {}" +
"}"
};
}
@Override
protected InspectionProfileEntry getInspection() {
return new MisorderedAssertEqualsParametersInspection();
}
}
@@ -0,0 +1,44 @@
/*
* Copyright 2000-2013 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.siyeh.ig.junit;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.siyeh.ig.LightInspectionTestCase;
/**
* @author Bas Leijdekkers
*/
public class UseOfObsoleteAssertInspectionTest extends LightInspectionTestCase {
public void testObsoleteAssert() { doTest(); }
@Override
protected String[] getEnvironmentClasses() {
return new String[] {
"package junit.framework;" +
"public class Assert {" +
" static public void assertEquals(String message, int expected, int actual) {}" +
"}",
"package org.junit;" +
"public class Assert {}"
};
}
@Override
protected InspectionProfileEntry getInspection() {
return new UseOfObsoleteAssertInspection();
}
}
@@ -31,6 +31,7 @@ import org.jetbrains.jps.model.library.JpsOrderRootType;
import org.jetbrains.jps.model.module.*;
import org.jetbrains.jps.model.serialization.JpsMacroExpander;
import org.jetbrains.jps.model.serialization.library.JpsLibraryTableSerializer;
import org.jetbrains.jps.model.serialization.library.JpsSdkTableSerializer;
import java.io.File;
import java.io.FilenameFilter;
@@ -96,6 +97,10 @@ class JpsEclipseClasspathReader extends AbstractEclipseClasspathReader<JpsModule
Collection<String> unknownJdks,
EclipseModuleManager eclipseModuleManager,
String jdkName) {
if (LOG.isDebugEnabled()) {
LOG.debug("loading " + rootModel.getName() + ": set module jdk " + jdkName);
}
rootModel.getDependenciesList().addSdkDependency(JpsJavaSdkType.INSTANCE);
}
@Override
@@ -35,6 +35,7 @@ import git4idea.commands.*;
import git4idea.repo.GitRemote;
import git4idea.repo.GitRepository;
import git4idea.repo.GitRepositoryManager;
import git4idea.util.GitFileUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -351,10 +352,7 @@ public abstract class CloudGitDeploymentRuntime<DC extends CloudDeploymentNameCo
protected void add() throws ServerRuntimeException {
try {
GitSimpleHandler handler = new GitSimpleHandler(getProject(), myContentRoot, GitCommand.ADD);
handler.setSilent(false);
handler.addParameters(".");
handler.run();
GitFileUtils.addFiles(getProject(), myContentRoot, myContentRoot);
}
catch (VcsException e) {
throw new ServerRuntimeException(e);
@@ -17,6 +17,7 @@ package org.jetbrains.plugins.gradle.model.builder;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ModuleIdentifier;
import org.gradle.api.artifacts.ModuleVersionIdentifier;
import org.gradle.plugins.ide.idea.GenerateIdeaModule;
import org.gradle.plugins.ide.idea.IdeaPlugin;
@@ -29,6 +30,7 @@ import org.jetbrains.plugins.gradle.model.ModelBuilderService;
import org.jetbrains.plugins.gradle.model.ProjectDependenciesModel;
import org.jetbrains.plugins.gradle.model.internal.*;
import java.io.Serializable;
import java.util.*;
/**
@@ -117,7 +119,7 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService {
(IdeDependenciesExtractor.IdeProjectDependency)versionId.getIdeDependency();
String ideaModuleName = findDeDuplicatedModuleName(projectDependency.getProject());
if(ideaModuleName == null) {
if (ideaModuleName == null) {
ideaModuleName = versionId.getName();
}
@@ -150,9 +152,9 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService {
@Nullable
private static String findDeDuplicatedModuleName(Project project) {
if(project.hasProperty(MODULE_PROPERTY)) {
if (project.hasProperty(MODULE_PROPERTY)) {
Object ideaModule = project.property(MODULE_PROPERTY);
if(ideaModule instanceof GenerateIdeaModule) {
if (ideaModule instanceof GenerateIdeaModule) {
GenerateIdeaModule generateIdeaModule = (GenerateIdeaModule)ideaModule;
return generateIdeaModule.getModule().getName();
}
@@ -189,7 +191,16 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService {
final GradleDependencyScope scope = GradleDependencyScope.fromName(configurationName);
if (scope == null) return;
ModuleVersionIdentifier dependencyId = dependency.getId();
final ModuleVersionIdentifier dependencyId;
if (dependency instanceof IdeDependenciesExtractor.UnresolvedIdeRepoFileDependency) {
IdeDependenciesExtractor.UnresolvedIdeRepoFileDependency unresolvedDependency =
(IdeDependenciesExtractor.UnresolvedIdeRepoFileDependency)dependency;
dependencyId = new MyModuleVersionIdentifier(unresolvedDependency.getFile().getName());
}
else {
dependencyId = dependency.getId();
}
DependencyVersionId versionId =
new DependencyVersionId(dependency, dependencyId.getName(), dependencyId.getGroup(), dependencyId.getVersion());
Scopes scopes = map.get(versionId);
@@ -218,4 +229,33 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService {
scopes.add(scope);
}
}
private static class MyModuleVersionIdentifier implements ModuleVersionIdentifier, Serializable {
private final String myName;
public MyModuleVersionIdentifier(String name) {
myName = name;
}
@Override
public String getVersion() {
return null;
}
@Override
public String getGroup() {
return null;
}
@Override
public String getName() {
return myName;
}
@Override
public ModuleIdentifier getModule() {
return null;
}
}
}
@@ -15,6 +15,7 @@
*/
package org.jetbrains.plugins.gradle.service.project;
import com.intellij.openapi.externalSystem.model.ExternalSystemException;
import org.gradle.tooling.BuildAction;
import org.gradle.tooling.BuildController;
import org.gradle.tooling.model.build.BuildEnvironment;
@@ -59,11 +60,20 @@ public class ProjectImportAction implements BuildAction<ProjectImportAction.AllM
for (IdeaModule module : ideaProject.getModules()) {
for (Class aClass : myExtraProjectModelClasses) {
Object extraProject = controller.findModel(module, aClass);
if (extraProject == null) continue;
allModels.addExtraProject(extraProject, aClass, module);
try {
Object extraProject = controller.findModel(module, aClass);
if (extraProject == null) continue;
allModels.addExtraProject(extraProject, aClass, module);
}
catch (Exception e) {
// do not fail project import in a preview mode
if (!myIsPreviewMode) {
throw new ExternalSystemException(e);
}
}
}
}
return allModels;
}
@@ -18,17 +18,18 @@ import com.intellij.openapi.roots.LanguageLevelModuleExtension;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.search.FilenameIndex;
import com.intellij.psi.search.FileTypeIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.util.PathUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.GroovyFileTypeLoader;
import org.jetbrains.plugins.groovy.GroovyFileType;
import org.jetbrains.plugins.groovy.debugger.filters.GroovyDebuggerSettings;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.Attributes;
import java.util.regex.Pattern;
@@ -42,29 +43,15 @@ public class GroovyHotSwapper extends JavaProgramPatcher {
private static final Pattern SPRING_LOADED_PATTERN = Pattern.compile("-javaagent:.+springloaded-core-[^/\\\\]+\\.jar");
private static boolean endsWithAny(String s, List<String> endings) {
for (String extension : endings) {
if (s.endsWith(extension)) {
return true;
private static boolean containsGroovyClasses(final Project project) {
return CachedValuesManager.getManager(project).getCachedValue(project, new CachedValueProvider<Boolean>() {
@Nullable
@Override
public Result<Boolean> compute() {
return Result.create(FileTypeIndex.containsFileOfType(GroovyFileType.GROOVY_FILE_TYPE, GlobalSearchScope.projectScope(project)),
PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
}
}
return false;
}
private static boolean containsGroovyClasses(Project project) {
final List<String> extensions = new ArrayList<String>();
for (String extension : GroovyFileTypeLoader.getAllGroovyExtensions()) {
extensions.add("." + extension);
}
final GlobalSearchScope scope = GlobalSearchScope.projectScope(project);
for (String fileName : FilenameIndex.getAllFilenames(project)) {
if (endsWithAny(fileName, extensions)) {
if (!FilenameIndex.getVirtualFilesByName(project, fileName, scope).isEmpty()) {
return true;
}
}
}
return false;
});
}
private static boolean hasSpringLoadedReloader(JavaParameters javaParameters) {
@@ -65,6 +65,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeParameterList;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.CompleteReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrBindingVariable;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.refactoring.DefaultGroovyVariableNameValidator;
@@ -450,6 +451,10 @@ public class GroovyCompletionContributor extends CompletionContributor {
object = ((GroovyResolveResult)object).getElement();
}
if (object instanceof GrBindingVariable && ((GrBindingVariable)object).getName().contains(CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED)) {
return;
}
if (!(lookupElement instanceof LookupElementBuilder) && inheritorsHolder.alreadyProcessed(lookupElement)) {
return;
}
@@ -1888,4 +1888,13 @@ class A {
}
""", "o", CompletionType.BASIC, CompletionResult.equal, 0)
}
void testIntellijIdeaRulezzzNotInCompletion() {
doVariantableTest('''\
def foo() {
def var
va<caret>r = 'abc'
}
''', '', CompletionType.BASIC, CompletionResult.notContain, 1, 'vaIntellijIdeaRulezzzr')
}
}
+11 -10
View File
@@ -242,7 +242,6 @@ public class HgVcs extends AbstractVcs<CommittedChangeList> {
return in;
}
@Override
public RootsConvertor getCustomConvertor() {
return HgRootsHandler.getInstance(myProject);
@@ -437,7 +436,6 @@ public class HgVcs extends AbstractVcs<CommittedChangeList> {
public void checkVersion() {
final String executable = getGlobalSettings().getHgExecutable();
HgCommandResultNotifier errorNotification = new HgCommandResultNotifier(myProject);
String message;
final String SETTINGS_LINK = "settings";
final String UPDATE_LINK = "update";
NotificationListener linkAdapter = new NotificationListener.Adapter() {
@@ -458,15 +456,15 @@ public class HgVcs extends AbstractVcs<CommittedChangeList> {
//if version is not supported, but have valid hg executable
if (!myVersion.isSupported()) {
LOG.info("Unsupported Hg version: " + myVersion);
message = String.format("The <a href='" + SETTINGS_LINK + "'>configured</a> version of Hg is not supported: %s.<br/> " +
"The minimal supported version is %s. Please <a href='" + UPDATE_LINK + "'>update</a>.",
myVersion, HgVersion.MIN);
String message = String.format("The <a href='" + SETTINGS_LINK + "'>configured</a> version of Hg is not supported: %s.<br/> " +
"The minimal supported version is %s. Please <a href='" + UPDATE_LINK + "'>update</a>.",
myVersion, HgVersion.MIN);
errorNotification.notifyError(null, "Unsupported Hg version", message, linkAdapter);
}
if (!unsupportedExtension.isEmpty()) {
else if (!unsupportedExtension.isEmpty()) {
LOG.warn("Unsupported Hg extensions: " + unsupportedExtension.toString());
message = String.format("Some hg extensions %s are not found or not supported by your hg version and will be ignored.\n" +
"Please, update your hgrc or Mercurial.ini file", unsupportedExtension.toString());
String message = String.format("Some hg extensions %s are not found or not supported by your hg version and will be ignored.\n" +
"Please, update your hgrc or Mercurial.ini file", unsupportedExtension.toString());
errorNotification.notifyWarning("Unsupported Hg version", message);
}
}
@@ -475,10 +473,13 @@ public class HgVcs extends AbstractVcs<CommittedChangeList> {
//sometimes not hg application has version command, but we couldn't parse an answer as valid hg,
// so parse(output) throw ParseException, but hg and git executable seems to be valid in this case
final String reason = (e.getCause() != null ? e.getCause() : e).getMessage();
message = HgVcsMessages.message("hg4idea.unable.to.run.hg", executable);
String message = HgVcsMessages.message("hg4idea.unable.to.run.hg", executable);
errorNotification.notifyError(null, message,
String.format(
reason + "<br/> Please check your hg executable path in <a href='" + SETTINGS_LINK + "'> settings </a>"),
reason +
"<br/> Please check your hg executable path in <a href='" +
SETTINGS_LINK +
"'> settings </a>"),
linkAdapter);
}
}
@@ -119,7 +119,7 @@ public class HgLogProvider implements VcsLogProvider {
}
String currentRevision = repository.getCurrentRevision();
if (currentRevision != null) { // null => fresh repository
refs.add(myVcsObjectsFactory.createRef(myVcsObjectsFactory.createHash(currentRevision), "HEAD", HgRefManager.HEAD, root));
refs.add(myVcsObjectsFactory.createRef(myVcsObjectsFactory.createHash(currentRevision), "tip", HgRefManager.HEAD, root));
}
for (HgNameWithHashInfo tagInfo : tags) {
refs.add(myVcsObjectsFactory.createRef(myVcsObjectsFactory.createHash(tagInfo.getHash()), tagInfo.getName(), HgRefManager.TAG, root));
@@ -24,6 +24,7 @@ import com.intellij.vcs.log.VcsLogObjectsFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgNameWithHashInfo;
import org.zmlx.hg4idea.HgVcs;
import java.io.File;
import java.util.*;
@@ -42,7 +43,8 @@ public class HgRepositoryReader {
private static Pattern HASH_NAME = Pattern.compile("\\s*([0-9a-fA-F]+)\\s+(.+)");
@NotNull private final File myHgDir; // .hg
@NotNull private final File myBranchHeadsFile; // .hg/cache/branchheads (does not exist before first commit)
@NotNull private final File myBranchHeadsFile; // .hg/cache/branchheads
@NotNull private final File myCacheDir; // .hg/cache (does not exist before first commit)
@NotNull private final File myCurrentBranch; // .hg/branch
@NotNull private final File myBookmarksFile; //.hg/bookmarks
@NotNull private final File myCurrentBookmark; //.hg/bookmarks.current
@@ -53,9 +55,11 @@ public class HgRepositoryReader {
public HgRepositoryReader(@NotNull Project project, @NotNull File hgDir) {
myHgDir = hgDir;
RepositoryUtil.assertFileExists(myHgDir, ".hg directory not found in " + myHgDir);
File branchesFile = new File(new File(myHgDir, "cache"), "branchheads-served"); //branchheads-served exist after mercurial 2.5,
myCacheDir = new File(myHgDir, "cache");
File branchesFile = new File(myCacheDir, "branchheads-served"); //branchheads-served exist after mercurial 2.5,
//before 2.5 only branchheads exist
myBranchHeadsFile = branchesFile.exists() ? branchesFile : new File(new File(myHgDir, "cache"), "branchheads");
HgVcs vcs = HgVcs.getInstance(project);
myBranchHeadsFile = vcs != null && vcs.getVersion().hasBranchHeadsServed() ? branchesFile : new File(myCacheDir, "branchheads");
myCurrentBranch = new File(myHgDir, "branch");
myBookmarksFile = new File(myHgDir, "bookmarks");
myCurrentBookmark = new File(myHgDir, "bookmarks.current");
@@ -71,7 +75,7 @@ public class HgRepositoryReader {
*/
@Nullable
public String readCurrentRevision() {
if (checkIsFresh()) return null;
if (checkIsFresh() || !myBranchHeadsFile.exists()) return null;
String[] branchesWithHeads = RepositoryUtil.tryLoadFile(myBranchHeadsFile).split("\n");
String head = branchesWithHeads[0];
Matcher matcher = HASH_NAME.matcher(head);
@@ -93,7 +97,7 @@ public class HgRepositoryReader {
public Collection<HgNameWithHashInfo> readBranches() {
List<HgNameWithHashInfo> branches = new ArrayList<HgNameWithHashInfo>();
// Set<String> branchNames = new HashSet<String>();
if (!checkIsFresh()) {
if (!checkIsFresh() && myBranchHeadsFile.exists()) {
String[] branchesWithHeads = RepositoryUtil.tryLoadFile(myBranchHeadsFile).split("\n");
// first one - is a head revision: head hash + head number;
for (int i = 1; i < branchesWithHeads.length; ++i) {
@@ -119,7 +123,7 @@ public class HgRepositoryReader {
}
public boolean checkIsFresh() {
return !myBranchHeadsFile.exists();
return !myCacheDir.exists();
}
public boolean branchExist() {
@@ -16,7 +16,6 @@ import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgProjectSettings;
import org.zmlx.hg4idea.HgVcs;
import org.zmlx.hg4idea.HgVcsMessages;
@@ -33,7 +32,7 @@ public class HgConfigurationProjectPanel {
private TextFieldWithBrowseButton myPathSelector;
private final HgVcs myVcs;
public HgConfigurationProjectPanel(@NotNull HgProjectSettings projectSettings, @Nullable Project project) {
public HgConfigurationProjectPanel(@NotNull HgProjectSettings projectSettings, @NotNull Project project) {
myProjectSettings = projectSettings;
myVcs = HgVcs.getInstance(project);
loadSettings();
@@ -652,7 +652,7 @@ public abstract class HgUtil {
userName = convertUserName(authorString);
email = "";
}
return new Pair<String, String>(userName, email);
return Pair.create(userName, email);
}
private static String convertUserName(@NotNull String userNameInfo) {
@@ -54,6 +54,7 @@ public final class HgVersion implements Comparable<HgVersion> {
// see http://mercurial.808500.n3.nabble.com/Bug-3887-New-hg-log-template-quot-rev-join-file-copies-n-quot-prints-literal-quot-sourcename-quot-fos-td4000129.html
public static final HgVersion BUILT_IN_FUNCTION_SUPPORTED = new HgVersion(2, 6, 0);
public static final HgVersion PARENT_REVISION_TEMPLATES_SUPPORTED = new HgVersion(2, 4, 0);
public static final HgVersion BRANCH_HEADS_SERVED_FILE_EXIST = new HgVersion(2, 5, 0);
//see http://selenic.com/pipermail/mercurial-devel/2013-May/051209.html fixed since 2.7
private static final HgVersion LARGEFILES_WITH_FOLLOW_SUPPORTED = new HgVersion(2, 7, 0);
@@ -157,6 +158,10 @@ public final class HgVersion implements Comparable<HgVersion> {
return !isNull() && compareTo(PARENT_REVISION_TEMPLATES_SUPPORTED) >= 0;
}
public boolean hasBranchHeadsServed() {
return !isNull() && compareTo(BRANCH_HEADS_SERVED_FILE_EXIST) >= 0;
}
/**
* Note: this class has a natural ordering that is inconsistent with equals.
* Two HgVersions are equal if their number versions are equal.
@@ -55,6 +55,7 @@ public abstract class HgPlatformTest extends UsefulTestCase {
protected VirtualFile myProjectRoot;
protected VirtualFile myRepository;
protected VirtualFile myChildRepo;
protected HgVcs myVcs;
protected static final String COMMIT_MESSAGE = "text";
@@ -79,9 +80,10 @@ public abstract class HgPlatformTest extends UsefulTestCase {
hg("version");
createRepository(myProjectRoot);
HgVcs hgVcs = HgVcs.getInstance(myProject);
assertNotNull(hgVcs);
hgVcs.getGlobalSettings().setHgExecutable(HgExecutor.getHgExecutable());
myVcs = HgVcs.getInstance(myProject);
assertNotNull(myVcs);
myVcs.getGlobalSettings().setHgExecutable(HgExecutor.getHgExecutable());
myVcs.checkVersion();
myRepository = myProjectRoot;
setUpHgrc(myRepository);
}
@@ -19,6 +19,7 @@ import com.intellij.dvcs.repo.Repository;
import com.intellij.openapi.vcs.VcsTestUtil;
import hg4idea.test.HgPlatformTest;
import org.jetbrains.annotations.NotNull;
import org.zmlx.hg4idea.HgVcs;
import org.zmlx.hg4idea.repo.HgRepositoryReader;
import org.zmlx.hg4idea.util.HgUtil;
@@ -18,6 +18,7 @@ package org.jetbrains.plugins.javaFX.packaging;
import com.intellij.execution.CommandLineUtil;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtilRt;
@@ -358,4 +359,6 @@ public abstract class AbstractJavaFxPackager {
public abstract String getPreloaderJar();
public abstract boolean convertCss2Bin();
public abstract List<JavaFxManifestAttribute> getCustomManifestAttributes();
}
@@ -106,7 +106,18 @@ public class JavaFxAntGenerator {
createJarTag.add(new SimpleTag("fileset", fileset2Jar.toArray(new Pair[fileset2Jar.size()])));
createJarTag.add(createResourcesTag(preloaderFiles, false, allButPreloader, allButSelf, all));
List<JavaFxManifestAttribute> manifestAttributes = packager.getCustomManifestAttributes();
if (manifestAttributes != null) {
final SimpleTag manifestTag = new SimpleTag("manifest");
for (JavaFxManifestAttribute pair : manifestAttributes) {
manifestTag.add(new SimpleTag("attribute",
new Pair<String, String>("name", pair.getName()),
new Pair<String, String>("value", pair.getValue())));
}
createJarTag.add(manifestTag);
}
topLevelTagsCollector.add(createJarTag);
//deploy task
@@ -0,0 +1,50 @@
package org.jetbrains.plugins.javaFX.packaging;
public class JavaFxManifestAttribute {
private String myName;
private String myValue;
public JavaFxManifestAttribute() {
}
public JavaFxManifestAttribute(String name, String value) {
myName = name;
myValue = value;
}
public String getName() {
return myName;
}
public void setName(String name) {
myName = name;
}
public String getValue() {
return myValue;
}
public void setValue(String value) {
myValue = value;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
JavaFxManifestAttribute attribute = (JavaFxManifestAttribute)o;
if (!myName.equals(attribute.myName)) return false;
if (!myValue.equals(attribute.myValue)) return false;
return true;
}
@Override
public int hashCode() {
int result = myName.hashCode();
result = 31 * result + myValue.hashCode();
return result;
}
}
@@ -15,6 +15,7 @@
*/
package org.jetbrains.plugins.javaFX.packaging;
import com.intellij.openapi.util.Pair;
import com.intellij.testFramework.UsefulTestCase;
import java.io.File;
@@ -215,6 +216,7 @@ public class JavaFxAntTaskTest extends UsefulTestCase{
private String myPreloaderJar;
private boolean myConvertCss2Bin;
private boolean mySigned;
private List<JavaFxManifestAttribute> myCustomManifestAttributes;
private MockJavaFxPackager(String outputPath) {
myOutputPath = outputPath;
@@ -365,5 +367,10 @@ public class JavaFxAntTaskTest extends UsefulTestCase{
public boolean convertCss2Bin() {
return myConvertCss2Bin;
}
@Override
public List<JavaFxManifestAttribute> getCustomManifestAttributes() {
return myCustomManifestAttributes;
}
}
}
@@ -31,6 +31,7 @@ import org.jetbrains.jps.model.java.JpsJavaSdkType;
import org.jetbrains.jps.model.library.sdk.JpsSdk;
import org.jetbrains.jps.model.library.sdk.JpsSdkType;
import org.jetbrains.plugins.javaFX.packaging.AbstractJavaFxPackager;
import org.jetbrains.plugins.javaFX.packaging.JavaFxManifestAttribute;
import org.jetbrains.plugins.javaFX.packaging.JavaFxPackagerConstants;
import org.jetbrains.plugins.javaFX.preloader.JpsJavaFxPreloaderArtifactProperties;
import org.jetbrains.plugins.javaFX.preloader.JpsJavaFxPreloaderArtifactType;
@@ -237,6 +238,11 @@ public class JpsJavaFxArtifactBuildTaskProvider extends ArtifactBuildTaskProvide
return myProperties.myState.isConvertCss2Bin();
}
@Override
public List<JavaFxManifestAttribute> getCustomManifestAttributes() {
return myProperties.myState.getCustomManifestAttributes();
}
private JpsArtifact getPreloaderArtifact() {
for (JpsPackagingElement element : myArtifact.getRootElement().getChildren()) {
if (element instanceof JpsArtifactOutputPackagingElement) {
@@ -2,8 +2,12 @@ package org.jetbrains.plugins.javaFX;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.model.ex.JpsElementBase;
import org.jetbrains.plugins.javaFX.packaging.JavaFxManifestAttribute;
import org.jetbrains.plugins.javaFX.packaging.JavaFxPackagerConstants;
import java.util.ArrayList;
import java.util.List;
/**
* User: anna
* Date: 3/13/13
@@ -36,6 +40,7 @@ public class JpsJavaFxArtifactProperties extends JpsElementBase<JpsJavaFxArtifac
myState.setAlias(state.myAlias);
myState.setConvertCss2Bin(state.myConvertCss2Bin);
myState.setNativeBundle(state.myNativeBundle);
myState.setCustomManifestAttributes(state.myCustomManifestAttributes);
}
@NotNull
@@ -67,6 +72,7 @@ public class JpsJavaFxArtifactProperties extends JpsElementBase<JpsJavaFxArtifac
private String myKeypass;
private boolean myConvertCss2Bin;
public JavaFxPackagerConstants.NativeBundles myNativeBundle = JavaFxPackagerConstants.NativeBundles.none;
private List<JavaFxManifestAttribute> myCustomManifestAttributes = new ArrayList<JavaFxManifestAttribute>();
public String getTitle() {
return myTitle;
@@ -203,5 +209,13 @@ public class JpsJavaFxArtifactProperties extends JpsElementBase<JpsJavaFxArtifac
public void setNativeBundle(JavaFxPackagerConstants.NativeBundles nativeBundle) {
myNativeBundle = nativeBundle;
}
public List<JavaFxManifestAttribute> getCustomManifestAttributes() {
return myCustomManifestAttributes;
}
public void setCustomManifestAttributes(List<JavaFxManifestAttribute> customManifestAttributes) {
myCustomManifestAttributes = customManifestAttributes;
}
}
}
@@ -25,6 +25,7 @@ import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.artifacts.ArtifactManager;
import com.intellij.packaging.artifacts.ArtifactProperties;
@@ -35,6 +36,7 @@ import com.intellij.packaging.impl.elements.ArtifactPackagingElement;
import com.intellij.packaging.ui.ArtifactEditorContext;
import com.intellij.packaging.ui.ArtifactPropertiesEditor;
import com.intellij.util.xmlb.XmlSerializerUtil;
import com.intellij.util.xmlb.annotations.Tag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.javaFX.packaging.preloader.JavaFxPreloaderArtifactProperties;
@@ -42,7 +44,9 @@ import org.jetbrains.plugins.javaFX.packaging.preloader.JavaFxPreloaderArtifactP
import org.jetbrains.plugins.javaFX.packaging.preloader.JavaFxPreloaderArtifactType;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
@@ -69,6 +73,7 @@ public class JavaFxArtifactProperties extends ArtifactProperties<JavaFxArtifactP
private String myKeypass;
private boolean myConvertCss2Bin;
private String myNativeBundle = JavaFxPackagerConstants.NativeBundles.none.name();
private List<JavaFxManifestAttribute> myCustomManifestAttributes = new ArrayList<JavaFxManifestAttribute>();
@Override
public void onBuildFinished(@NotNull final Artifact artifact, @NotNull final CompileContext compileContext) {
@@ -298,6 +303,14 @@ public class JavaFxArtifactProperties extends ArtifactProperties<JavaFxArtifactP
myNativeBundle = nativeBundle;
}
public List<JavaFxManifestAttribute> getCustomManifestAttributes() {
return myCustomManifestAttributes;
}
public void setCustomManifestAttributes(List<JavaFxManifestAttribute> customManifestAttributes) {
myCustomManifestAttributes = customManifestAttributes;
}
public static abstract class JavaFxPackager extends AbstractJavaFxPackager {
private final Artifact myArtifact;
private final JavaFxArtifactProperties myProperties;
@@ -423,5 +436,10 @@ public class JavaFxArtifactProperties extends ArtifactProperties<JavaFxArtifactP
public boolean isEnabledSigning() {
return myProperties.isEnabledSigning();
}
@Override
public List<JavaFxManifestAttribute> getCustomManifestAttributes() {
return myProperties.getCustomManifestAttributes();
}
}
}
@@ -3,12 +3,12 @@
<grid id="27dc6" binding="myWholePanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
<xy x="20" y="20" width="500" height="422"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="ca833" layout-manager="GridLayoutManager" row-count="12" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="ca833" layout-manager="GridLayoutManager" row-count="13" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -215,6 +215,37 @@
</constraints>
<properties/>
</component>
<component id="7d6a7" class="javax.swing.JLabel">
<constraints>
<grid row="12" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Custom manifest attributes"/>
</properties>
</component>
<grid id="cd6c2" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="12" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="bacf3" class="javax.swing.JButton" binding="myEditAttributesButton" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Edit Attributes"/>
</properties>
</component>
<hspacer id="20f71">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
</children>
</grid>
<vspacer id="1a12e">
@@ -15,21 +15,27 @@
*/
package org.jetbrains.plugins.javaFX.packaging;
import com.intellij.execution.util.ListTableWithButtons;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.ui.ArtifactPropertiesEditor;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Base64Converter;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.ListTableModel;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
@@ -56,7 +62,10 @@ public class JavaFxArtifactPropertiesEditor extends ArtifactPropertiesEditor {
private JButton myEditSignCertificateButton;
private JCheckBox myConvertCssToBinCheckBox;
private JComboBox myNativeBundleCB;
private JButton myEditAttributesButton;
private JavaFxEditCertificatesDialog myDialog;
private CustomManifestAttributesDialog myManifestAttributesDialog;
private List<JavaFxManifestAttribute> myCustomManifestAttributes;
public JavaFxArtifactPropertiesEditor(JavaFxArtifactProperties properties, final Project project, Artifact artifact) {
super();
@@ -79,6 +88,17 @@ public class JavaFxArtifactPropertiesEditor extends ArtifactPropertiesEditor {
}
});
myEditAttributesButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myManifestAttributesDialog = new CustomManifestAttributesDialog(myWholePanel, myCustomManifestAttributes);
myManifestAttributesDialog.show();
if (myManifestAttributesDialog.isOK()) {
myCustomManifestAttributes = myManifestAttributesDialog.getAttrs();
}
}
});
final List<String> bundleNames = new ArrayList<String>();
for (JavaFxPackagerConstants.NativeBundles bundle : JavaFxPackagerConstants.NativeBundles.values()) {
bundleNames.add(bundle.name());
@@ -121,13 +141,17 @@ public class JavaFxArtifactPropertiesEditor extends ArtifactPropertiesEditor {
if (isModified(storepass != null ? Base64Converter.decode(storepass) : "", myDialog.myPanel.myStorePassTF)) return true;
if (myProperties.isSelfSigning() != myDialog.myPanel.mySelfSignedRadioButton.isSelected()) return true;
}
if (myManifestAttributesDialog != null) {
if (!Comparing.equal(myManifestAttributesDialog.getAttrs(), myProperties.getCustomManifestAttributes())) return true;
}
return false;
}
private static boolean isModified(final String title, JTextComponent tf) {
return !Comparing.strEqual(title, tf.getText().trim());
}
private static boolean isModified(final String title, TextFieldWithBrowseButton tf) {
return !Comparing.strEqual(title, tf.getText().trim());
}
@@ -142,7 +166,7 @@ public class JavaFxArtifactPropertiesEditor extends ArtifactPropertiesEditor {
myProperties.setHeight(myHeightTF.getText());
myProperties.setHtmlParamFile(myHtmlParams.getText());
myProperties.setParamFile(myParams.getText());
myProperties.setUpdateMode(myUpdateInBackgroundCB.isSelected() ? JavaFxPackagerConstants.UPDATE_MODE_BACKGROUND
myProperties.setUpdateMode(myUpdateInBackgroundCB.isSelected() ? JavaFxPackagerConstants.UPDATE_MODE_BACKGROUND
: JavaFxPackagerConstants.UPDATE_MODE_ALWAYS);
myProperties.setEnabledSigning(myEnableSigningCB.isSelected());
myProperties.setConvertCss2Bin(myConvertCssToBinCheckBox.isSelected());
@@ -156,6 +180,10 @@ public class JavaFxArtifactPropertiesEditor extends ArtifactPropertiesEditor {
final String storePass = String.valueOf(myDialog.myPanel.myStorePassTF.getPassword());
myProperties.setStorepass(!StringUtil.isEmptyOrSpaces(storePass) ? Base64Converter.encode(storePass) : null);
}
if (myManifestAttributesDialog != null) {
myProperties.setCustomManifestAttributes(myManifestAttributesDialog.getAttrs());
}
}
@Nullable
@@ -179,6 +207,7 @@ public class JavaFxArtifactPropertiesEditor extends ArtifactPropertiesEditor {
myEnableSigningCB.setSelected(myProperties.isEnabledSigning());
myConvertCssToBinCheckBox.setSelected(myProperties.isConvertCss2Bin());
myEditSignCertificateButton.setEnabled(myProperties.isEnabledSigning());
myCustomManifestAttributes = myProperties.getCustomManifestAttributes();
}
private static void setText(TextFieldWithBrowseButton tf, final String title) {
@@ -199,4 +228,107 @@ public class JavaFxArtifactPropertiesEditor extends ArtifactPropertiesEditor {
myDialog.myPanel = null;
}
}
}
private static class CustomManifestAttributesDialog extends DialogWrapper {
private final JPanel myWholePanel = new JPanel(new BorderLayout());
private final AttributesTable myTable;
protected CustomManifestAttributesDialog(JPanel panel, List<JavaFxManifestAttribute> attrs) {
super(panel, true);
myTable = new AttributesTable();
myTable.setValues(attrs);
myWholePanel.add(myTable.getComponent(), BorderLayout.CENTER);
setTitle("Edit Custom Manifest Attributes");
init();
}
@Override
@Nullable
protected JComponent createCenterPanel() {
return myWholePanel;
}
@Override
protected void doOKAction() {
myTable.stopEditing();
super.doOKAction();
}
List<JavaFxManifestAttribute> getAttrs() {
return myTable.getAttrs();
}
private static class AttributesTable extends ListTableWithButtons<JavaFxManifestAttribute> {
@Override
protected ListTableModel createListModel() {
final ColumnInfo name = new ElementsColumnInfoBase<JavaFxManifestAttribute>("Name") {
@Nullable
@Override
public String valueOf(JavaFxManifestAttribute attribute) {
return attribute.getName();
}
@Override
public boolean isCellEditable(JavaFxManifestAttribute attr) {
return true;
}
@Override
public void setValue(JavaFxManifestAttribute attr, String value) {
attr.setName(value);
}
@Nullable
@Override
protected String getDescription(JavaFxManifestAttribute element) {
return element.getName();
}
};
final ColumnInfo value = new ElementsColumnInfoBase<JavaFxManifestAttribute>("Value") {
@Override
public String valueOf(JavaFxManifestAttribute attr) {
return attr.getValue();
}
@Override
public boolean isCellEditable(JavaFxManifestAttribute attr) {
return true;
}
@Override
public void setValue(JavaFxManifestAttribute attr, String s) {
attr.setValue(s);
}
@Nullable
@Override
protected String getDescription(JavaFxManifestAttribute attr) {
return attr.getValue();
}
};
return new ListTableModel((new ColumnInfo[]{name, value}));
}
@Override
protected JavaFxManifestAttribute createElement() {
return new JavaFxManifestAttribute("", "");
}
@Override
protected JavaFxManifestAttribute cloneElement(JavaFxManifestAttribute attribute) {
return new JavaFxManifestAttribute(attribute.getName(), attribute.getValue());
}
@Override
protected boolean canDeleteElement(JavaFxManifestAttribute selection) {
return true;
}
public List<JavaFxManifestAttribute> getAttrs() {
return getElements();
}
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2013 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.
@@ -15,195 +15,15 @@
*/
package com.theoryinpractice.testng.inspection;
import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.InheritanceUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import com.siyeh.ig.junit.MisorderedAssertEqualsArgumentsInspectionBase;
/**
* @author Bas Leijdekkers
*/
public class MisorderedAssertEqualsArgumentsTestNGInspection extends BaseJavaLocalInspectionTool {
public class MisorderedAssertEqualsArgumentsTestNGInspection extends MisorderedAssertEqualsArgumentsInspectionBase {
private static class FlipParametersFix implements LocalQuickFix {
@Override
@NotNull
public String getName() {
return "Flip compared arguments";
}
@NotNull
@Override
public String getFamilyName() {
return getName();
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement methodNameIdentifier = descriptor.getPsiElement();
final PsiElement parent = methodNameIdentifier.getParent();
if (parent == null) {
return;
}
final PsiMethodCallExpression callExpression = (PsiMethodCallExpression)parent.getParent();
if (callExpression == null) {
return;
}
final PsiReferenceExpression methodExpression = callExpression.getMethodExpression();
final PsiMethod method = (PsiMethod)methodExpression.resolve();
if (method == null) {
return;
}
final PsiClass containingClass = method.getContainingClass();
final boolean junit;
if (InheritanceUtil.isInheritor(containingClass, "org.testng.Assert")) {
junit = false;
}
else if (InheritanceUtil.isInheritor(containingClass, "org.testng.AssertJUnit")) {
junit = true;
}
else {
return;
}
final PsiParameterList parameterList = method.getParameterList();
final PsiParameter[] parameters = parameterList.getParameters();
final PsiManager psiManager = callExpression.getManager();
final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
final PsiType stringType = PsiType.getJavaLangString(psiManager, scope);
final PsiType parameterType1 = parameters[0].getType();
final PsiExpressionList argumentList = callExpression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
final PsiExpression expectedArgument;
final PsiExpression actualArgument;
if (junit) {
if (parameterType1.equals(stringType) && parameters.length > 2) {
expectedArgument = arguments[1];
actualArgument = arguments[2];
}
else {
expectedArgument = arguments[0];
actualArgument = arguments[1];
}
}
else {
actualArgument = arguments[0];
expectedArgument = arguments[1];
}
final PsiElement copy = expectedArgument.copy();
expectedArgument.replace(actualArgument);
actualArgument.replace(copy);
}
}
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
return new MisorderedAssertEqualsParametersVisitor(holder);
}
private static class MisorderedAssertEqualsParametersVisitor extends JavaElementVisitor {
private final ProblemsHolder myProblemsHolder;
public MisorderedAssertEqualsParametersVisitor(ProblemsHolder problemsHolder) {
myProblemsHolder = problemsHolder;
}
@Override
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression);
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
@NonNls final String methodName = methodExpression.getReferenceName();
if (!"assertEquals".equals(methodName) && !"assertEqualsNoOrder".equals(methodName) &&
!"assertNotEquals".equals(methodName) && !"assertArrayEquals".equals(methodName)) {
return;
}
final PsiMethod method = expression.resolveMethod();
if (method == null) {
return;
}
final PsiManager manager = expression.getManager();
final Project project = manager.getProject();
final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
final PsiType stringType = PsiType.getJavaLangString(manager, scope);
final PsiExpressionList argumentList = expression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
if (arguments.length < 2) {
return;
}
final PsiClass containingClass = method.getContainingClass();
final PsiExpression expectedArgument;
final PsiExpression actualArgument;
if (InheritanceUtil.isInheritor(containingClass, "org.testng.AssertJUnit")) {
final PsiType firstArgumentType = arguments[0].getType();
if (stringType.equals(firstArgumentType) && arguments.length > 2) {
expectedArgument = arguments[1];
actualArgument = arguments[2];
}
else {
expectedArgument = arguments[0];
actualArgument = arguments[1];
}
} else if (InheritanceUtil.isInheritor(containingClass, "org.testng.Assert")){
actualArgument = arguments[0];
expectedArgument = arguments[1];
} else {
return;
}
if (expectedArgument == null || actualArgument == null) {
return;
}
if (isLiteralOrConstant(expectedArgument)) {
return;
}
if (!isLiteralOrConstant(actualArgument)) {
return;
}
final PsiElement referenceNameElement = methodExpression.getReferenceNameElement();
if (referenceNameElement != null) {
myProblemsHolder.registerProblem(referenceNameElement, "Arguments to <code>#ref()</code> in wrong order #loc",
new FlipParametersFix());
}
else {
myProblemsHolder.registerProblem(methodExpression, "Arguments to <code>#ref()</code> in wrong order #loc",
new FlipParametersFix());
}
}
private static boolean isLiteralOrConstant(PsiExpression expression) {
if (expression instanceof PsiLiteralExpression) {
return true;
}
else if (expression instanceof PsiNewExpression) {
final PsiNewExpression newExpression = (PsiNewExpression)expression;
final PsiExpressionList argumentList = newExpression.getArgumentList();
if (argumentList == null) {
return true;
}
for (PsiExpression argument : argumentList.getExpressions()) {
if (!isLiteralOrConstant(argument)) {
return false;
}
}
return true;
}
if (!(expression instanceof PsiReferenceExpression)) {
return false;
}
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression;
final PsiElement target = referenceExpression.resolve();
if (!(target instanceof PsiField)) {
return false;
}
final PsiField field = (PsiField)target;
return field.hasModifierProperty(PsiModifier.STATIC) && field.hasModifierProperty(PsiModifier.FINAL);
}
public boolean checkTestNG() {
return true;
}
}
@@ -6,6 +6,6 @@ will behave fine for assertions which pass, but may give confusing error reports
arguments differ.
<!-- tooltip end -->
<p>
<small>New in 12, Powered TestNG-J</small>
<small>New in 12, Powered by TestNG-J</small>
</body>
</html>
@@ -131,7 +131,7 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider
private FixableMessageAction myWarnAction;
private JPanel myErrorPanel;
private JPanel myErrorMessages;
protected JPanel myErrorMessages;
private JPanel myErrorStackPanel;
private CardLayout myErrorStackLayout;
private JTextArea myErrorStack;
@@ -386,7 +386,7 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider
repaint();
}
private void addErrorMessage(final FixableMessageInfo message, Icon icon) {
protected void addErrorMessage(final FixableMessageInfo message, Icon icon) {
if (message.myLinkText.length() > 0 || message.myAfterLinkText.length() > 0) {
HyperlinkLabel warnLabel = new HyperlinkLabel();
warnLabel.setOpaque(false);