mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+8
-5
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -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;
|
||||
}
|
||||
|
||||
+2
-3
@@ -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));
|
||||
}
|
||||
|
||||
+14
-1
@@ -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();
|
||||
|
||||
+2
-2
@@ -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);
|
||||
|
||||
+4
@@ -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();
|
||||
|
||||
|
||||
+13
-6
@@ -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();
|
||||
|
||||
+6
-6
@@ -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() {
|
||||
|
||||
+44
@@ -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;
|
||||
|
||||
+7
-1
@@ -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};
|
||||
}
|
||||
|
||||
+12
@@ -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>;};
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
</problems>
|
||||
+7
@@ -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();
|
||||
|
||||
+4
-2
@@ -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();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
+45
-3
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -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);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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"
|
||||
|
||||
+4
-4
@@ -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()'
|
||||
|
||||
+10
-24
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+193
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-157
@@ -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;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -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 -->
|
||||
|
||||
-16
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+14
@@ -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>);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+21
@@ -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>);
|
||||
}
|
||||
}
|
||||
+16
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -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);
|
||||
}
|
||||
}
|
||||
+33
@@ -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();
|
||||
}
|
||||
}
|
||||
+47
@@ -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();
|
||||
}
|
||||
}
|
||||
+44
@@ -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();
|
||||
}
|
||||
}
|
||||
+5
@@ -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
|
||||
|
||||
+2
-4
@@ -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);
|
||||
|
||||
+44
-4
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-3
@@ -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) {
|
||||
|
||||
+5
@@ -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;
|
||||
}
|
||||
|
||||
+9
@@ -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')
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
+3
@@ -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();
|
||||
}
|
||||
|
||||
+12
-1
@@ -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
|
||||
|
||||
+50
@@ -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;
|
||||
}
|
||||
}
|
||||
+7
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -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) {
|
||||
|
||||
+14
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+18
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+33
-2
@@ -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">
|
||||
|
||||
+135
-3
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-185
@@ -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;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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>
|
||||
+2
-2
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user