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:
Generated
-2
@@ -3,8 +3,6 @@
|
||||
<output-path>$PROJECT_DIR$/out/artifacts/jps</output-path>
|
||||
<root id="archive" name="jps-plugins.jar">
|
||||
<element id="module-output" name="jps-appLauncher" />
|
||||
<element id="module-output" name="jps-gwt" />
|
||||
<element id="module-output" name="jps-jpa" />
|
||||
<element id="module-output" name="jps-scala" />
|
||||
</root>
|
||||
</artifact>
|
||||
|
||||
Generated
-2
@@ -60,8 +60,6 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/jps/jps.iml" filepath="$PROJECT_DIR$/jps/jps.iml" group="jps" />
|
||||
<module fileurl="file://$PROJECT_DIR$/jps/plugins/appLauncher/jps-appLauncher.iml" filepath="$PROJECT_DIR$/jps/plugins/appLauncher/jps-appLauncher.iml" group="jps" />
|
||||
<module fileurl="file://$PROJECT_DIR$/jps/jps-builders/jps-builders.iml" filepath="$PROJECT_DIR$/jps/jps-builders/jps-builders.iml" group="jps" />
|
||||
<module fileurl="file://$PROJECT_DIR$/jps/plugins/gwt/jps-gwt.iml" filepath="$PROJECT_DIR$/jps/plugins/gwt/jps-gwt.iml" group="jps" />
|
||||
<module fileurl="file://$PROJECT_DIR$/jps/plugins/jpa/jps-jpa.iml" filepath="$PROJECT_DIR$/jps/plugins/jpa/jps-jpa.iml" group="jps" />
|
||||
<module fileurl="file://$PROJECT_DIR$/jps/model/jps-model.iml" filepath="$PROJECT_DIR$/jps/model/jps-model.iml" group="jps" />
|
||||
<module fileurl="file://$PROJECT_DIR$/jps/plugins/scala/jps-scala.iml" filepath="$PROJECT_DIR$/jps/plugins/scala/jps-scala.iml" group="jps" />
|
||||
<module fileurl="file://$PROJECT_DIR$/jps/jps-tests.iml" filepath="$PROJECT_DIR$/jps/jps-tests.iml" group="jps" />
|
||||
|
||||
@@ -157,6 +157,7 @@ libraryLicense(name: "Axis", libraryName: "axis-1.4", version: "1.4", license: "
|
||||
libraryLicense(name: "CGLib", libraryName: "CGLIB", version: "2.2.2", license: "Apache", url: "http://cglib.sourceforge.net/", licenseUrl: "http://www.apache.org/foundation/licence-FAQ.html")
|
||||
libraryLicense(name: "classworlds", libraryName: "classworlds-1.1.jar", version: "1.1", license: "codehaus", url: "http://classworlds.codehaus.org/", licenseUrl: "http://classworlds.codehaus.org/license.html")
|
||||
libraryLicense(name: "Android SDK Tools", libraryName: "android-sdk-tools", license: "Apache 2.0", url: "http://source.android.com/")
|
||||
libraryLicense(name: "Android SDK Tools JPS", libraryName: "android-sdk-tools-jps", license: "Apache 2.0", url: "http://source.android.com/")
|
||||
libraryLicense(name: "Apache Commons BeanUtils", libraryName: "commons-beanutils.jar", version: "1.6", license: "Apache 2.0", url: "http://commons.apache.org/beanutils/")
|
||||
libraryLicense(name: "Apache Commons Codec", libraryName: "commons-codec", version: "1.3", license: "Apache 2.0", url: "http://commons.apache.org/codec/", licenseUrl: "http://commons.apache.org/license.html")
|
||||
libraryLicense(name: "Apache Commons Collections", libraryName: "commons-collections", version: "3.1", license: "Apache 2.0", url: "http://commons.apache.org/collections/", licenseUrl: "http://commons.apache.org/license.html")
|
||||
@@ -239,4 +240,3 @@ jetbrainsLibrary("JPS")
|
||||
jetbrainsLibrary("Maven Embedder")
|
||||
jetbrainsLibrary("tcServiceMessages")
|
||||
jetbrainsLibrary("optimizedFileManager.jar")
|
||||
jetbrainsLibrary("RunTime")
|
||||
|
||||
@@ -19,11 +19,13 @@ import com.intellij.codeInsight.lookup.*;
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.util.ClassConditionKey;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@@ -65,7 +67,16 @@ public class JavaChainLookupElement extends LookupElementDecorator<LookupElement
|
||||
}
|
||||
|
||||
private String maybeAddParentheses(String s) {
|
||||
return myQualifier.getObject() instanceof PsiMethod ? s + "()" : s;
|
||||
return getQualifierObject() instanceof PsiMethod ? s + "()" : s;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Object getQualifierObject() {
|
||||
Object qObject = myQualifier.getObject();
|
||||
if (qObject instanceof ResolveResult) {
|
||||
qObject = ((ResolveResult)qObject).getElement();
|
||||
}
|
||||
return qObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -76,6 +87,10 @@ public class JavaChainLookupElement extends LookupElementDecorator<LookupElement
|
||||
String name = maybeAddParentheses(qualifierPresentation.getItemText());
|
||||
final String qualifierText = myQualifier.as(CastingLookupElementDecorator.CLASS_CONDITION_KEY) != null ? "(" + name + ")" : name;
|
||||
presentation.setItemText(qualifierText + "." + presentation.getItemText());
|
||||
|
||||
if (getQualifierObject() instanceof PsiClass) {
|
||||
presentation.setTailText(StringUtil.notNullize(presentation.getTailText()) + qualifierPresentation.getTailText());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,7 +114,7 @@ public class JavaChainLookupElement extends LookupElementDecorator<LookupElement
|
||||
CompletionUtil.emulateInsertion(getDelegate(), context.getTailOffset(), context);
|
||||
}
|
||||
|
||||
private static boolean shouldParenthesizeQualifier(final PsiFile file, final int startOffset, final int endOffset) {
|
||||
protected boolean shouldParenthesizeQualifier(final PsiFile file, final int startOffset, final int endOffset) {
|
||||
PsiElement element = file.findElementAt(startOffset);
|
||||
if (element == null) {
|
||||
return false;
|
||||
|
||||
+4
-3
@@ -57,7 +57,8 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
|
||||
CompletionResultSet result = _result.withPrefixMatcher(CompletionUtil.findReferenceOrAlphanumericPrefix(parameters));
|
||||
addAllClasses(parameters, JavaCompletionSorting.addJavaSorting(parameters, result), parameters.getInvocationCount() <= 1, new Consumer<LookupElement>() {
|
||||
addAllClasses(parameters, parameters.getInvocationCount() <= 1,
|
||||
JavaCompletionSorting.addJavaSorting(parameters, result).getPrefixMatcher(), new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement element) {
|
||||
_result.addElement(element);
|
||||
@@ -68,8 +69,8 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
|
||||
public static void addAllClasses(CompletionParameters parameters,
|
||||
final CompletionResultSet result,
|
||||
final boolean filterByScope,
|
||||
@NotNull final PrefixMatcher matcher,
|
||||
@NotNull final Consumer<LookupElement> consumer) {
|
||||
final PsiElement insertedElement = parameters.getPosition();
|
||||
|
||||
@@ -110,7 +111,7 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
|
||||
final boolean lookingForAnnotations = PsiJavaPatterns.psiElement().afterLeaf("@").accepts(insertedElement);
|
||||
AllClassesGetter.processJavaClasses(parameters, result.getPrefixMatcher(), filterByScope, new Consumer<PsiClass>() {
|
||||
AllClassesGetter.processJavaClasses(parameters, matcher, filterByScope, new Consumer<PsiClass>() {
|
||||
@Override
|
||||
public void consume(PsiClass psiClass) {
|
||||
if (lookingForAnnotations && !psiClass.isAnnotationType()) return;
|
||||
|
||||
+2
-2
@@ -106,7 +106,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
withParent(or(psiElement(PsiResourceVariable.class), psiElement(PsiResourceList.class)))));
|
||||
|
||||
@Nullable
|
||||
private static ElementFilter getReferenceFilter(PsiElement position) {
|
||||
public static ElementFilter getReferenceFilter(PsiElement position) {
|
||||
// Completion after extends in interface, type parameter and implements in class
|
||||
final PsiClass containingClass = PsiTreeUtil.getParentOfType(position, PsiClass.class, false, PsiCodeBlock.class, PsiMethod.class, PsiExpressionList.class, PsiVariable.class);
|
||||
if (containingClass != null && psiElement().afterLeaf(PsiKeyword.EXTENDS, PsiKeyword.IMPLEMENTS, ",", "&").accepts(position)) {
|
||||
@@ -239,7 +239,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
if (!isClassNamePossible(parameters.getPosition()) || !mayStartClassName(result, parameters.isRelaxedMatching())) return;
|
||||
|
||||
if (mayShowAllClasses(parameters)) {
|
||||
JavaClassNameCompletionContributor.addAllClasses(parameters, result, parameters.getInvocationCount() <= 2, new Consumer<LookupElement>() {
|
||||
JavaClassNameCompletionContributor.addAllClasses(parameters, parameters.getInvocationCount() <= 2, result.getPrefixMatcher(), new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement element) {
|
||||
if (!inheritors.alreadyProcessed(element)) {
|
||||
|
||||
@@ -346,6 +346,9 @@ public class JavaCompletionUtil {
|
||||
|
||||
@Nullable
|
||||
private static PsiType getPsiType(final Object o) {
|
||||
if (o instanceof ResolveResult) {
|
||||
return getPsiType(((ResolveResult)o).getElement());
|
||||
}
|
||||
if (o instanceof PsiVariable) {
|
||||
return ((PsiVariable)o).getType();
|
||||
}
|
||||
|
||||
+89
-20
@@ -15,10 +15,21 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
|
||||
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiJavaCodeReferenceElement;
|
||||
import com.intellij.psi.PsiReferenceExpression;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.filters.ElementFilter;
|
||||
import com.intellij.util.CollectConsumer;
|
||||
import com.intellij.util.Consumer;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
@@ -26,29 +37,87 @@ public class JavaNoVariantsDelegator extends NoVariantsDelegator {
|
||||
|
||||
@Override
|
||||
protected void delegate(CompletionParameters parameters, CompletionResultSet result, Consumer<CompletionResult> passResult) {
|
||||
if (parameters.getCompletionType() == CompletionType.BASIC &&
|
||||
parameters.getInvocationCount() <= 1 &&
|
||||
JavaCompletionContributor.mayStartClassName(result, false) &&
|
||||
JavaCompletionContributor.isClassNamePossible(parameters.getPosition())) {
|
||||
final ClassByNameMerger merger = new ClassByNameMerger(parameters.getInvocationCount() == 0, result);
|
||||
if (parameters.getCompletionType() == CompletionType.BASIC) {
|
||||
PsiElement position = parameters.getPosition();
|
||||
if (parameters.getInvocationCount() <= 1 &&
|
||||
JavaCompletionContributor.mayStartClassName(result, false) &&
|
||||
JavaCompletionContributor.isClassNamePossible(position)) {
|
||||
suggestNonImportedClasses(parameters, result);
|
||||
return;
|
||||
}
|
||||
|
||||
JavaClassNameCompletionContributor.addAllClasses(parameters, JavaCompletionSorting.addJavaSorting(parameters, result),
|
||||
true, new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement element) {
|
||||
JavaPsiClassReferenceElement classElement = element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY);
|
||||
if (classElement != null) {
|
||||
classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
|
||||
}
|
||||
suggestChainedCalls(parameters, result, position);
|
||||
}
|
||||
|
||||
merger.consume(classElement);
|
||||
}
|
||||
});
|
||||
|
||||
merger.finishedClassProcessing();
|
||||
|
||||
} else if (parameters.getCompletionType() == CompletionType.SMART && parameters.getInvocationCount() == 2) {
|
||||
if (parameters.getCompletionType() == CompletionType.SMART && parameters.getInvocationCount() == 2) {
|
||||
result.runRemainingContributors(parameters.withInvocationCount(3), passResult);
|
||||
}
|
||||
}
|
||||
|
||||
private static void suggestChainedCalls(CompletionParameters parameters, CompletionResultSet result, PsiElement position) {
|
||||
PsiElement parent = position.getParent();
|
||||
if (!(parent instanceof PsiJavaCodeReferenceElement)) {
|
||||
return;
|
||||
}
|
||||
PsiElement qualifier = ((PsiJavaCodeReferenceElement)parent).getQualifier();
|
||||
if (!(qualifier instanceof PsiJavaCodeReferenceElement) ||
|
||||
((PsiJavaCodeReferenceElement)qualifier).isQualified() ||
|
||||
((PsiJavaCodeReferenceElement)qualifier).resolve() != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String fullPrefix = position.getContainingFile().getText().substring(parent.getTextRange().getStartOffset(), parameters.getOffset());
|
||||
CompletionResultSet qualifiedCollector = result.withPrefixMatcher(fullPrefix);
|
||||
ElementFilter filter = JavaCompletionContributor.getReferenceFilter(position);
|
||||
for (LookupElement base : suggestQualifierItems(parameters, (PsiJavaCodeReferenceElement)qualifier, filter)) {
|
||||
PsiType type = JavaCompletionUtil.getLookupElementType(base);
|
||||
if (type != null && !PsiType.VOID.equals(type)) {
|
||||
PsiReferenceExpression ref = ReferenceExpressionCompletionContributor.createMockReference(position, type, base);
|
||||
for (final LookupElement item : JavaSmartCompletionContributor.completeReference(position, ref, filter, true, true, parameters,
|
||||
result.getPrefixMatcher())) {
|
||||
qualifiedCollector.addElement(new JavaChainLookupElement(base, item));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<LookupElement> suggestQualifierItems(CompletionParameters parameters,
|
||||
PsiJavaCodeReferenceElement qualifier,
|
||||
ElementFilter filter) {
|
||||
String referenceName = qualifier.getReferenceName();
|
||||
if (referenceName == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
PrefixMatcher qMatcher = new CamelHumpMatcher(referenceName);
|
||||
Set<LookupElement> plainVariants =
|
||||
JavaSmartCompletionContributor.completeReference(qualifier, qualifier, filter, true, true, parameters, qMatcher);
|
||||
if (!plainVariants.isEmpty()) {
|
||||
return plainVariants;
|
||||
}
|
||||
|
||||
final Set<LookupElement> allClasses = new LinkedHashSet<LookupElement>();
|
||||
JavaClassNameCompletionContributor.addAllClasses(parameters.withPosition(qualifier.getReferenceNameElement(), qualifier.getTextRange().getEndOffset()),
|
||||
true, qMatcher, new CollectConsumer<LookupElement>(allClasses));
|
||||
return allClasses;
|
||||
}
|
||||
|
||||
private static void suggestNonImportedClasses(CompletionParameters parameters, CompletionResultSet result) {
|
||||
final ClassByNameMerger merger = new ClassByNameMerger(parameters.getInvocationCount() == 0, result);
|
||||
|
||||
JavaClassNameCompletionContributor.addAllClasses(parameters,
|
||||
true, JavaCompletionSorting.addJavaSorting(parameters, result).getPrefixMatcher(), new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement element) {
|
||||
JavaPsiClassReferenceElement classElement = element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY);
|
||||
if (classElement != null) {
|
||||
classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
|
||||
}
|
||||
|
||||
merger.consume(classElement);
|
||||
}
|
||||
});
|
||||
|
||||
merger.finishedClassProcessing();
|
||||
}
|
||||
}
|
||||
|
||||
+19
-10
@@ -155,14 +155,15 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
final ElementFilter filter = getReferenceFilter(element);
|
||||
if (filter != null) {
|
||||
final List<ExpectedTypeInfo> infos = Arrays.asList(getExpectedTypes(parameters));
|
||||
for (final LookupElement item : completeReference(element, reference, filter, true, parameters)) {
|
||||
for (final LookupElement item : completeReference(element, reference, filter, true, false, parameters, result.getPrefixMatcher())) {
|
||||
if (item.getObject() instanceof PsiClass) {
|
||||
result.addElement(decorate(LookupElementDecorator.withInsertHandler((LookupItem)item, ConstructorInsertHandler.SMART_INSTANCE), infos));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (INSIDE_TYPECAST_EXPRESSION.accepts(element)) {
|
||||
for (final LookupElement item : completeReference(element, reference, new GeneratorFilter(AssignableToFilter.class, new CastTypeGetter()), false, parameters)) {
|
||||
for (final LookupElement item : completeReference(element, reference, new GeneratorFilter(AssignableToFilter.class, new CastTypeGetter()), false, true, parameters,
|
||||
result.getPrefixMatcher())) {
|
||||
result.addElement(item);
|
||||
}
|
||||
}
|
||||
@@ -182,7 +183,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
final PsiElement element = parameters.getPosition();
|
||||
final PsiReference reference = element.getContainingFile().findReferenceAt(parameters.getOffset());
|
||||
assert reference != null;
|
||||
for (final LookupElement item : completeReference(element, reference, THROWABLES_FILTER, true, parameters)) {
|
||||
for (final LookupElement item : completeReference(element, reference, THROWABLES_FILTER, true, false, parameters, result.getPrefixMatcher())) {
|
||||
result.addElement(item);
|
||||
}
|
||||
}
|
||||
@@ -456,7 +457,12 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
return ExpectedTypesProvider.getExpectedTypes(expression, true, parameters.getCompletionType() == CompletionType.SMART, false);
|
||||
}
|
||||
|
||||
static Set<LookupElement> completeReference(final PsiElement element, PsiReference reference, final ElementFilter filter, final boolean acceptClasses, CompletionParameters parameters) {
|
||||
static Set<LookupElement> completeReference(final PsiElement element,
|
||||
PsiReference reference,
|
||||
final ElementFilter filter,
|
||||
final boolean acceptClasses,
|
||||
final boolean acceptMembers,
|
||||
CompletionParameters parameters, @Nullable final PrefixMatcher matcher) {
|
||||
if (reference instanceof PsiMultiReference) {
|
||||
reference = ContainerUtil.findInstance(((PsiMultiReference) reference).getReferences(), PsiJavaReference.class);
|
||||
}
|
||||
@@ -470,15 +476,18 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
|
||||
public boolean isClassAcceptable(Class hintClass) {
|
||||
if (acceptClasses) {
|
||||
return ReflectionCache.isAssignable(PsiClass.class, hintClass);
|
||||
if (ReflectionCache.isAssignable(PsiClass.class, hintClass)) {
|
||||
return acceptClasses;
|
||||
}
|
||||
|
||||
return ReflectionCache.isAssignable(PsiVariable.class, hintClass) ||
|
||||
ReflectionCache.isAssignable(PsiMethod.class, hintClass) ||
|
||||
ReflectionCache.isAssignable(CandidateInfo.class, hintClass);
|
||||
if (ReflectionCache.isAssignable(PsiVariable.class, hintClass) ||
|
||||
ReflectionCache.isAssignable(PsiMethod.class, hintClass) ||
|
||||
ReflectionCache.isAssignable(CandidateInfo.class, hintClass)) {
|
||||
return acceptMembers;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}, true, parameters.getInvocationCount() <= 1, null, parameters);
|
||||
}, true, parameters.getInvocationCount() <= 1, matcher, parameters);
|
||||
}
|
||||
|
||||
return Collections.emptySet();
|
||||
|
||||
+34
-20
@@ -33,8 +33,11 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.filters.*;
|
||||
import com.intellij.psi.filters.element.ModifierFilter;
|
||||
import com.intellij.psi.filters.types.AssignableFromFilter;
|
||||
import com.intellij.psi.impl.FakePsiElement;
|
||||
import com.intellij.psi.impl.light.LightVariableBuilder;
|
||||
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
@@ -122,7 +125,7 @@ public class ReferenceExpressionCompletionContributor {
|
||||
final boolean secondTime = parameters.getParameters().getInvocationCount() >= 2;
|
||||
|
||||
final Set<LookupElement> base =
|
||||
JavaSmartCompletionContributor.completeReference(element, reference, filter, false, parameters.getParameters());
|
||||
JavaSmartCompletionContributor.completeReference(element, reference, filter, false, true, parameters.getParameters(), null);
|
||||
for (final LookupElement item : base) {
|
||||
addSingleArrayElementAccess(element, item, parameters, result);
|
||||
}
|
||||
@@ -177,7 +180,7 @@ public class ReferenceExpressionCompletionContributor {
|
||||
public boolean isClassAcceptable(Class hintClass) {
|
||||
return true;
|
||||
}
|
||||
}), false, parameters.getParameters());
|
||||
}), false, true, parameters.getParameters(), null);
|
||||
for (LookupElement lookupElement : elements) {
|
||||
if (lookupElement.getObject() instanceof PsiMethod) {
|
||||
final JavaMethodCallElement item = lookupElement.as(JavaMethodCallElement.CLASS_CONDITION_KEY);
|
||||
@@ -419,32 +422,43 @@ public class ReferenceExpressionCompletionContributor {
|
||||
final Consumer<LookupElement> result,
|
||||
PsiType qualifierType,
|
||||
final PsiType expectedType, JavaSmartCompletionParameters parameters) throws IncorrectOperationException {
|
||||
final JavaCodeFragmentFactory factory = JavaCodeFragmentFactory.getInstance(place.getProject());
|
||||
PsiType varType = qualifierType;
|
||||
if (varType instanceof PsiEllipsisType) {
|
||||
varType = ((PsiEllipsisType)varType).getComponentType();
|
||||
}
|
||||
if (varType instanceof PsiWildcardType || varType instanceof PsiCapturedWildcardType) {
|
||||
varType = TypeConversionUtil.erasure(expectedType);
|
||||
}
|
||||
|
||||
final String typeText = varType.getCanonicalText();
|
||||
final JavaCodeFragment block = factory.createCodeBlockCodeFragment(typeText + " xxx;xxx.xxx;", place, false);
|
||||
final PsiElement secondChild = block.getChildren()[1];
|
||||
if (!(secondChild instanceof PsiExpressionStatement)) {
|
||||
LOG.error(typeText + " of " + varType.getClass());
|
||||
}
|
||||
final PsiExpressionStatement expressionStatement = (PsiExpressionStatement)secondChild;
|
||||
final PsiReferenceExpression mockRef = (PsiReferenceExpression) expressionStatement.getExpression();
|
||||
final PsiReferenceExpression mockRef = createMockReference(place, qualifierType, qualifierItem);
|
||||
|
||||
final ElementFilter filter = getReferenceFilter(place, true);
|
||||
for (final LookupElement item : completeFinalReference(place, mockRef, filter, parameters)) {
|
||||
if (shoudChain(place, varType, expectedType, item)) {
|
||||
if (shoudChain(place, qualifierType, expectedType, item)) {
|
||||
result.consume(new JavaChainLookupElement(qualifierItem, item));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static PsiReferenceExpression createMockReference(final PsiElement place, @NotNull PsiType qualifierType, LookupElement qualifierItem) {
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(place.getProject());
|
||||
if (qualifierItem.getObject() instanceof PsiClass) {
|
||||
return (PsiReferenceExpression)factory
|
||||
.createExpressionFromText(((PsiClass)qualifierItem.getObject()).getQualifiedName() + ".xxx", place);
|
||||
}
|
||||
|
||||
return (PsiReferenceExpression) factory.createExpressionFromText("xxx.xxx", createContextWithXxxVariable(place, qualifierType));
|
||||
}
|
||||
|
||||
public static FakePsiElement createContextWithXxxVariable(final PsiElement place, final PsiType varType) {
|
||||
return new FakePsiElement() {
|
||||
@Override
|
||||
public boolean processDeclarations(@NotNull PsiScopeProcessor processor,
|
||||
@NotNull ResolveState state,
|
||||
PsiElement lastParent,
|
||||
@NotNull PsiElement place) {
|
||||
return processor.execute(new LightVariableBuilder("xxx", varType, place), ResolveState.initial());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getParent() {
|
||||
return place;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static boolean shoudChain(PsiElement element, PsiType qualifierType, PsiType expectedType, LookupElement item) {
|
||||
if (item.getObject() instanceof PsiMethod) {
|
||||
final PsiMethod method = (PsiMethod)item.getObject();
|
||||
|
||||
+1
@@ -122,6 +122,7 @@ public class PullAsAbstractUpFix extends LocalQuickFixAndIntentionActionOnPsiEle
|
||||
}
|
||||
|
||||
private static void pullUp(PsiMethod method, PsiClass containingClass, PsiClass baseClass) {
|
||||
if (!CodeInsightUtilBase.prepareFileForWrite(baseClass.getContainingFile())) return;
|
||||
final MemberInfo memberInfo = new MemberInfo(method);
|
||||
memberInfo.setChecked(true);
|
||||
memberInfo.setToAbstract(true);
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.filters.ClassFilter;
|
||||
import com.intellij.psi.filters.position.SuperParentFilter;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
@@ -146,6 +147,11 @@ public class JavaTypedHandler extends TypedHandlerDelegate {
|
||||
handleAfterJavaLT(editor, JavaTokenType.LT, JavaTokenType.GT, INVALID_INSIDE_REFERENCE);
|
||||
return Result.STOP;
|
||||
}
|
||||
else if (c == ':') {
|
||||
if (autoIndentCase(editor, project, file)) {
|
||||
return Result.STOP;
|
||||
}
|
||||
}
|
||||
return Result.CONTINUE;
|
||||
}
|
||||
|
||||
@@ -283,4 +289,18 @@ public class JavaTypedHandler extends TypedHandlerDelegate {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean autoIndentCase(Editor editor, Project project, PsiFile file) {
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
|
||||
PsiElement currElement = file.findElementAt(offset - 1);
|
||||
if (currElement != null) {
|
||||
PsiElement parent = currElement.getParent();
|
||||
if (parent != null && parent instanceof PsiSwitchLabelStatement) {
|
||||
CodeStyleManager.getInstance(project).adjustLineIndent(file, parent.getTextOffset());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -45,6 +45,7 @@ import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -85,8 +86,10 @@ public class JavaVariableInplaceIntroducer extends InplaceVariableIntroducer<Psi
|
||||
myPointer = declarationStatement != null ? SmartPointerManager.getInstance(project).createSmartPsiElementPointer(declarationStatement) : null;
|
||||
editor.putUserData(ReassignVariableUtil.DECLARATION_KEY, myPointer);
|
||||
if (occurrenceMarkers != null) {
|
||||
final ArrayList<RangeMarker> rangeMarkers = new ArrayList<RangeMarker>(occurrenceMarkers);
|
||||
rangeMarkers.add(exprMarker);
|
||||
editor.putUserData(ReassignVariableUtil.OCCURRENCES_KEY,
|
||||
occurrenceMarkers.toArray(new RangeMarker[occurrenceMarkers.size()]));
|
||||
rangeMarkers.toArray(new RangeMarker[rangeMarkers.size()]));
|
||||
}
|
||||
myExpression = expression;
|
||||
final PsiType defaultType = elementToRename.getType();
|
||||
|
||||
+6
-2
@@ -24,6 +24,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.file.JavaDirectoryServiceImpl;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.PsiUtilBase;
|
||||
import com.intellij.refactoring.move.MoveCallback;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
@@ -76,9 +77,12 @@ public class JavaMoveFilesOrDirectoriesHandler extends MoveFilesOrDirectoriesHan
|
||||
@Override
|
||||
protected void run(Result<PsiElement[]> result) throws Throwable {
|
||||
final List<PsiElement> adjustedElements = new ArrayList<PsiElement>();
|
||||
for (PsiElement element : elements) {
|
||||
for (int i = 0, length = elements.length; i < length; i++) {
|
||||
PsiElement element = elements[i];
|
||||
if (element instanceof PsiClass) {
|
||||
final PsiFile containingFile = obtainContainingFile(element, elements);
|
||||
final PsiClass topLevelClass = PsiUtil.getTopLevelClass(element);
|
||||
elements[i] = topLevelClass;
|
||||
final PsiFile containingFile = obtainContainingFile(topLevelClass, elements);
|
||||
if (containingFile != null && !adjustedElements.contains(containingFile)) {
|
||||
adjustedElements.add(containingFile);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CommandLineWrapper {
|
||||
private static final String PREFIX = "-D";
|
||||
|
||||
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException,
|
||||
IllegalAccessException, IOException, InstantiationException {
|
||||
@@ -54,9 +55,41 @@ public class CommandLineWrapper {
|
||||
reader.close();
|
||||
}
|
||||
file.delete();
|
||||
String progClass = args[1];
|
||||
String[] progArgs = new String[args.length - 2];
|
||||
System.arraycopy(args, 2, progArgs, 0, progArgs.length);
|
||||
|
||||
int startArgsIdx = 2;
|
||||
if (args[1].equals("@vm_params")) {
|
||||
startArgsIdx = 4;
|
||||
final File vmParamsFile = new File(args[2]);
|
||||
final BufferedReader vmParamsReader = new BufferedReader(new FileReader(vmParamsFile));
|
||||
try {
|
||||
while (vmParamsReader.ready()) {
|
||||
final String vmParam = vmParamsReader.readLine().trim();
|
||||
final int eqIdx = vmParam.indexOf("=");
|
||||
String vmParamName;
|
||||
String vmParamValue;
|
||||
|
||||
if (eqIdx > -1 && eqIdx < vmParam.length() - 1) {
|
||||
vmParamName = vmParam.substring(0, eqIdx);
|
||||
vmParamValue = vmParam.substring(eqIdx + 1);
|
||||
} else {
|
||||
vmParamName = vmParam;
|
||||
vmParamValue = "";
|
||||
}
|
||||
vmParamName = vmParamName.trim();
|
||||
if (vmParamName.startsWith(PREFIX)) {
|
||||
vmParamName = vmParamName.substring(PREFIX.length());
|
||||
System.setProperty(vmParamName, vmParamValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
vmParamsReader.close();
|
||||
}
|
||||
vmParamsFile.delete();
|
||||
}
|
||||
String progClass = args[startArgsIdx - 1];
|
||||
String[] progArgs = new String[args.length - startArgsIdx];
|
||||
System.arraycopy(args, startArgsIdx, progArgs, 0, progArgs.length);
|
||||
ClassLoader loader = new URLClassLoader((URL[])urls.toArray(new URL[urls.size()]), null);
|
||||
final String classloader = System.getProperty("java.system.class.loader");
|
||||
if (classloader != null) {
|
||||
|
||||
@@ -1221,4 +1221,16 @@ class Foo {{
|
||||
myFixture.checkResult 'class Foo { int foo() { re(<caret>) }}'
|
||||
}
|
||||
|
||||
public void testAmbiguousClassQualifier() {
|
||||
myFixture.addClass("package foo; public class Util { public static void foo() {} }")
|
||||
myFixture.addClass("package bar; public class Util { public static void bar() {} }")
|
||||
myFixture.configureByText 'a.java', 'class Foo {{ <caret> }}'
|
||||
type 'Util.'
|
||||
assert myFixture.lookupElementStrings == ['Util.bar', 'Util.foo']
|
||||
type 'fo\n'
|
||||
myFixture.checkResult '''import foo.Util;
|
||||
|
||||
class Foo {{ Util.foo();<caret> }}'''
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Generated
-8
@@ -1,8 +0,0 @@
|
||||
<component name="ArtifactManager">
|
||||
<artifact type="jar" name="jps-gwt">
|
||||
<output-path>$PROJECT_DIR$/out/artifacts</output-path>
|
||||
<root id="archive" name="jps-gwt.jar">
|
||||
<element id="module-output" name="gwt" />
|
||||
</root>
|
||||
</artifact>
|
||||
</component>
|
||||
Generated
-8
@@ -1,8 +0,0 @@
|
||||
<component name="ArtifactManager">
|
||||
<artifact type="jar" name="jps-javaee">
|
||||
<output-path>$PROJECT_DIR$/out/artifacts</output-path>
|
||||
<root id="archive" name="jps-javaee.jar">
|
||||
<element id="module-output" name="javaee" />
|
||||
</root>
|
||||
</artifact>
|
||||
</component>
|
||||
Generated
-8
@@ -1,8 +0,0 @@
|
||||
<component name="ArtifactManager">
|
||||
<artifact type="jar" name="jps-jpa">
|
||||
<output-path>$PROJECT_DIR$/out/artifacts</output-path>
|
||||
<root id="archive" name="jps-jpa.jar">
|
||||
<element id="module-output" name="jpa" />
|
||||
</root>
|
||||
</artifact>
|
||||
</component>
|
||||
Generated
-3
@@ -3,9 +3,6 @@
|
||||
<output-path>$PROJECT_DIR$/out/artifacts</output-path>
|
||||
<root id="archive" name="jps-sources.zip">
|
||||
<element id="dir-copy" path="$PROJECT_DIR$/src" />
|
||||
<element id="dir-copy" path="$PROJECT_DIR$/plugins/javaee/src" />
|
||||
<element id="dir-copy" path="$PROJECT_DIR$/plugins/gwt/src" />
|
||||
<element id="dir-copy" path="$PROJECT_DIR$/plugins/jpa/src" />
|
||||
<element id="dir-copy" path="$PROJECT_DIR$/antLayout/src" />
|
||||
<element id="dir-copy" path="$PROJECT_DIR$/serverFacade/src" />
|
||||
</root>
|
||||
|
||||
@@ -77,11 +77,13 @@ public class IncProjectBuilder {
|
||||
}
|
||||
catch (ProjectBuildException e) {
|
||||
final Throwable cause = e.getCause();
|
||||
if (cause instanceof PersistentEnumerator.CorruptedException || cause instanceof MappingFailedException) {
|
||||
if (cause instanceof PersistentEnumerator.CorruptedException || cause instanceof MappingFailedException || cause instanceof IOException) {
|
||||
// force rebuild
|
||||
myMessageDispatcher.processMessage(new CompilerMessage(COMPILE_SERVER_NAME, BuildMessage.Kind.INFO,
|
||||
"Internal caches are corrupted or have outdated format, forcing project rebuild: " +
|
||||
e.getMessage()));
|
||||
myMessageDispatcher.processMessage(new CompilerMessage(
|
||||
COMPILE_SERVER_NAME, BuildMessage.Kind.INFO,
|
||||
"Internal caches are corrupted or have outdated format, forcing project rebuild: " +
|
||||
e.getMessage())
|
||||
);
|
||||
flushContext(context);
|
||||
context = createContext(new AllProjectScope(scope.getProject(), Collections.<Artifact>emptySet(), true), false, true);
|
||||
runBuild(context);
|
||||
|
||||
@@ -77,10 +77,10 @@ public class FieldPropertyTest extends IncrementalTestCase {
|
||||
}
|
||||
|
||||
public void testNonIncremental1() throws Exception {
|
||||
doTest();
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNonIncremental2() throws Exception {
|
||||
doTest();
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ import com.intellij.openapi.application.ex.PathManagerEx;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import junit.framework.TestCase;
|
||||
import junitx.framework.FileAssert;
|
||||
import org.apache.log4j.Level;
|
||||
import org.apache.log4j.PropertyConfigurator;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -342,7 +342,9 @@ public abstract class IncrementalTestCase extends TestCase {
|
||||
new AllProjectScope(project, Collections.<Artifact>emptySet(), false), true, false
|
||||
);
|
||||
|
||||
FileAssert.assertEquals(new File(getBaseDir() + ".log"), new File(getWorkDir() + ".log"));
|
||||
final String expected = StringUtil.convertLineSeparators(FileUtil.loadFile(new File(getBaseDir() + ".log")));
|
||||
final String actual = StringUtil.convertLineSeparators(FileUtil.loadFile(new File(getWorkDir() + ".log")));
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
finally {
|
||||
projectDescriptor.release();
|
||||
|
||||
@@ -28,5 +28,6 @@ public class Callbacks {
|
||||
void associate(String classFileName, SourceFileNameLookup sourceLookup, ClassReader cr);
|
||||
void markOverride(String className, String methodName, String methodSignature);
|
||||
void registerConstantUsage(String className, String fieldName, String fieldOwner);
|
||||
void registerImports(Collection<String> imports, String rootClass);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,10 +35,18 @@ public class Mappings {
|
||||
private boolean myIsDifferentiated = false;
|
||||
|
||||
private final List<DependencyContext.S> myChangedClasses;
|
||||
private final List<DependencyContext.S> myChangedFiles;
|
||||
|
||||
private void addChangedClass(final DependencyContext.S it) {
|
||||
assert (myChangedClasses != null);
|
||||
assert (myChangedClasses != null && myChangedFiles != null);
|
||||
myChangedClasses.add(it);
|
||||
|
||||
final DependencyContext.S file = myClassToSourceFile.get(it);
|
||||
|
||||
if (file != null) {
|
||||
myChangedFiles.add(it);
|
||||
}
|
||||
|
||||
myIsDifferentiated = true;
|
||||
}
|
||||
|
||||
@@ -46,6 +54,10 @@ public class Mappings {
|
||||
return myChangedClasses;
|
||||
}
|
||||
|
||||
private Collection<DependencyContext.S> getChangedFiles() {
|
||||
return myChangedFiles;
|
||||
}
|
||||
|
||||
private boolean isDifferentiated() {
|
||||
return myIsDifferentiated;
|
||||
}
|
||||
@@ -110,6 +122,7 @@ public class Mappings {
|
||||
private Mappings(final Mappings base) throws IOException {
|
||||
myIsDelta = true;
|
||||
myChangedClasses = new LinkedList<DependencyContext.S>();
|
||||
myChangedFiles = new LinkedList<DependencyContext.S>();
|
||||
myDeltaIsTransient = base.myDeltaIsTransient;
|
||||
myRootDir = new File(FileUtil.toSystemIndependentName(base.myRootDir.getAbsolutePath()) + File.separatorChar + "delta");
|
||||
myContext = base.myContext;
|
||||
@@ -121,6 +134,7 @@ public class Mappings {
|
||||
public Mappings(final File rootDir, final boolean transientDelta) throws IOException {
|
||||
myIsDelta = false;
|
||||
myChangedClasses = null;
|
||||
myChangedFiles = null;
|
||||
myDeltaIsTransient = transientDelta;
|
||||
myRootDir = rootDir;
|
||||
createImplementation();
|
||||
@@ -1579,9 +1593,32 @@ public class Mappings {
|
||||
myClassToSourceFile.putAll(delta.myClassToSourceFile);
|
||||
}
|
||||
|
||||
mySourceFileToClasses.putAll(delta.mySourceFileToClasses);
|
||||
mySourceFileToUsages.putAll(delta.mySourceFileToUsages);
|
||||
mySourceFileToAnnotationUsages.putAll(delta.mySourceFileToAnnotationUsages);
|
||||
if (delta.isDifferentiated()) {
|
||||
for (DependencyContext.S f : delta.getChangedFiles()) {
|
||||
mySourceFileToClasses.remove(f);
|
||||
final Collection<ClassRepr> classes = delta.mySourceFileToClasses.get(f);
|
||||
if (classes != null){
|
||||
mySourceFileToClasses.put(f, classes);
|
||||
}
|
||||
|
||||
mySourceFileToUsages.remove(f);
|
||||
final Collection<UsageRepr.Cluster> clusters = delta.mySourceFileToUsages.get(f);
|
||||
if (clusters != null){
|
||||
mySourceFileToUsages.put(f, clusters);
|
||||
}
|
||||
|
||||
mySourceFileToAnnotationUsages.remove(f);
|
||||
final Collection<UsageRepr.Usage> usages = delta.mySourceFileToAnnotationUsages.get(f);
|
||||
if (usages != null){
|
||||
mySourceFileToAnnotationUsages.put(f, usages);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
mySourceFileToClasses.putAll(delta.mySourceFileToClasses);
|
||||
mySourceFileToUsages.putAll(delta.mySourceFileToUsages);
|
||||
mySourceFileToAnnotationUsages.putAll(delta.mySourceFileToAnnotationUsages);
|
||||
}
|
||||
|
||||
final Collection<DependencyContext.S> compiledSet = new HashSet<DependencyContext.S>(compiled.size());
|
||||
|
||||
@@ -1682,6 +1719,24 @@ public class Mappings {
|
||||
public void registerConstantUsage(final String className, final String fieldName, final String fieldOwner) {
|
||||
//To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerImports(final Collection<String> imports, final String rootClass) {
|
||||
final DependencyContext.S rootClassName = myContext.get(rootClass);
|
||||
final DependencyContext.S fileName = myClassToSourceFile.get(rootClassName);
|
||||
|
||||
for (final String i : imports) {
|
||||
final DependencyContext.S iname = myContext.get(i);
|
||||
|
||||
myClassToClassDependency.put(rootClassName, iname);
|
||||
|
||||
if (fileName != null) {
|
||||
final UsageRepr.Cluster cluster = new UsageRepr.Cluster();
|
||||
cluster.addUsage(rootClassName, UsageRepr.createClassUsage(myContext, iname));
|
||||
mySourceFileToUsages.put(fileName, cluster);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="jps" />
|
||||
<orderEntry type="library" name="Groovy" level="project" />
|
||||
<orderEntry type="library" name="JUnit4" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
-1
@@ -1 +0,0 @@
|
||||
org.jetbrains.jps.gwt.GwtCompilerOutputElementType
|
||||
@@ -1 +0,0 @@
|
||||
org.jetbrains.jps.gwt.GwtModuleBuilderService
|
||||
@@ -1 +0,0 @@
|
||||
org.jetbrains.jps.gwt.GwtFacetType
|
||||
@@ -1,32 +0,0 @@
|
||||
package org.jetbrains.jps.gwt
|
||||
|
||||
import org.jetbrains.jps.artifacts.ComplexLayoutElement
|
||||
import org.jetbrains.jps.artifacts.LayoutElement
|
||||
import org.jetbrains.jps.Project
|
||||
import org.jetbrains.jps.idea.IdeaProjectLoadingUtil
|
||||
import org.jetbrains.jps.idea.Facet
|
||||
import org.jetbrains.jps.artifacts.DirectoryCopyElement
|
||||
import org.jetbrains.jps.idea.ProjectLoadingErrorReporter
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
class GwtCompilerOutputElement extends ComplexLayoutElement {
|
||||
String facetId
|
||||
ProjectLoadingErrorReporter errorReporter
|
||||
|
||||
@Override
|
||||
List<LayoutElement> getSubstitution(Project project) {
|
||||
Facet facet = IdeaProjectLoadingUtil.findFacetByIdWithAssertion(project, facetId, errorReporter)
|
||||
if (!(facet instanceof GwtFacet)) {
|
||||
errorReporter.error("'$facetId' is not GWT facet!")
|
||||
}
|
||||
|
||||
GwtFacet gwtFacet = (GwtFacet)facet
|
||||
return [new DirectoryCopyElement(dirPath: gwtFacet.tempOutputDir)]
|
||||
}
|
||||
|
||||
Facet findFacet(Project project) {
|
||||
return IdeaProjectLoadingUtil.findFacetById(project, facetId)
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package org.jetbrains.jps.gwt
|
||||
|
||||
import org.jetbrains.jps.MacroExpander
|
||||
import org.jetbrains.jps.Project
|
||||
import org.jetbrains.jps.artifacts.LayoutElement
|
||||
import org.jetbrains.jps.artifacts.LayoutElementTypeService
|
||||
import org.jetbrains.jps.idea.ProjectLoadingErrorReporter
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class GwtCompilerOutputElementType extends LayoutElementTypeService {
|
||||
public GwtCompilerOutputElementType() {
|
||||
super("gwt-compiler-output")
|
||||
}
|
||||
|
||||
@Override
|
||||
public LayoutElement createElement(Project project, Node tag, MacroExpander macroExpander, ProjectLoadingErrorReporter errorReporter) {
|
||||
return new GwtCompilerOutputElement(facetId: tag."@facet", errorReporter: errorReporter)
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package org.jetbrains.jps.gwt
|
||||
|
||||
import org.jetbrains.jps.Module
|
||||
import org.jetbrains.jps.idea.Facet
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
class GwtFacet extends Facet {
|
||||
Module module
|
||||
String compilerMaxHeapSize = "128"
|
||||
String scriptOutputStyle = "DETAILED"
|
||||
String additionalCompilerParameters = ""
|
||||
String sdkPath
|
||||
String tempOutputDir
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package org.jetbrains.jps.gwt
|
||||
|
||||
import org.jetbrains.jps.MacroExpander
|
||||
import org.jetbrains.jps.Module
|
||||
import org.jetbrains.jps.idea.Facet
|
||||
import org.jetbrains.jps.idea.FacetTypeService
|
||||
|
||||
import org.jetbrains.jps.idea.IdeaProjectLoadingUtil
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
class GwtFacetType extends FacetTypeService {
|
||||
GwtFacetType() {
|
||||
super("gwt")
|
||||
}
|
||||
|
||||
@Override
|
||||
Facet createFacet(Module module, String name, Node facetConfiguration, MacroExpander macroExpander) {
|
||||
def facet = new GwtFacet(module: module, name: name)
|
||||
facetConfiguration.setting.each {Node child ->
|
||||
String value = child."@value"
|
||||
switch (child."@name") {
|
||||
case "compilerMaxHeapSize":
|
||||
facet.compilerMaxHeapSize = Integer.parseInt(value)
|
||||
break
|
||||
case "gwtScriptOutputStyle":
|
||||
facet.scriptOutputStyle = value
|
||||
break
|
||||
case "additionalCompilerParameters":
|
||||
facet.additionalCompilerParameters = value
|
||||
break
|
||||
case "gwtSdkUrl":
|
||||
facet.sdkPath = macroExpander.expandMacros(IdeaProjectLoadingUtil.pathFromUrl(value))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return facet
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
package org.jetbrains.jps.gwt
|
||||
|
||||
import org.jetbrains.jps.ModuleBuildState
|
||||
import org.jetbrains.jps.ModuleBuilder
|
||||
import org.jetbrains.jps.ModuleChunk
|
||||
import org.jetbrains.jps.Project
|
||||
import org.jetbrains.jps.artifacts.LayoutElement
|
||||
import org.jetbrains.jps.artifacts.ArtifactLayoutElement
|
||||
import org.jetbrains.jps.builders.BuildUtil
|
||||
import org.jetbrains.jps.ProjectBuilder
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
class GwtModuleBuilder implements ModuleBuilder {
|
||||
def processModule(ModuleBuildState state, ModuleChunk moduleChunk, ProjectBuilder projectBuilder) {
|
||||
List<GwtFacet> facets = []
|
||||
moduleChunk.modules.each {
|
||||
it.facets.values().each {
|
||||
if (it instanceof GwtFacet) {
|
||||
facets << it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (facets.isEmpty()) return
|
||||
|
||||
facets.each {GwtFacet facet ->
|
||||
compileGwtFacet(facet, projectBuilder, state)
|
||||
}
|
||||
}
|
||||
|
||||
def compileGwtFacet(GwtFacet facet, ProjectBuilder projectBuilder, ModuleBuildState state) {
|
||||
if (!isIncludedInArtifact(facet, projectBuilder.project)) {
|
||||
projectBuilder.info("GWT Facet in module '${facet.module.name}' isn't included in artifacts so GWT compiler won't be called")
|
||||
return
|
||||
}
|
||||
|
||||
if (facet.tempOutputDir != null) return
|
||||
|
||||
if (!new File(facet.sdkPath).exists()) {
|
||||
projectBuilder.error("GWT SDK directory $facet.sdkPath not found")
|
||||
}
|
||||
|
||||
List<String> gwtModules = GwtModulesSearcher.findGwtModules(facet.module.sourceRoots)
|
||||
if (gwtModules.isEmpty()) {
|
||||
projectBuilder.info("No GWT modules found in GWT facet in ${facet.module} module")
|
||||
return
|
||||
}
|
||||
|
||||
String outputDir = projectBuilder.getTempDirectoryPath("GWT_Output_$facet.module.name")
|
||||
facet.tempOutputDir = outputDir
|
||||
|
||||
def ant = projectBuilder.binding.ant
|
||||
BuildUtil.deleteDir(projectBuilder, outputDir)
|
||||
ant.mkdir(dir: outputDir)
|
||||
|
||||
gwtModules.each {String moduleName ->
|
||||
projectBuilder.stage("Compiling GWT Module")
|
||||
ant.java(fork: "true", classname: "com.google.gwt.dev.Compiler", failonerror: "true") {
|
||||
jvmarg(line: "-Xmx${facet.compilerMaxHeapSize}m")
|
||||
if (!facet.additionalCompilerParameters.isEmpty()) {
|
||||
jvmarg(line: facet.additionalCompilerParameters)
|
||||
}
|
||||
classpath {
|
||||
pathelement(location: "${facet.sdkPath}/gwt-dev.jar")
|
||||
state.sourceRootsFromModuleWithDependencies.each {
|
||||
pathelement(location: it)
|
||||
}
|
||||
state.classpath.each {
|
||||
pathelement(location: it)
|
||||
}
|
||||
}
|
||||
arg(value: "-war")
|
||||
arg(value: outputDir)
|
||||
arg(value: "-style")
|
||||
arg(value: facet.scriptOutputStyle)
|
||||
arg(value: moduleName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isIncludedInArtifact(GwtFacet gwtFacet, Project project) {
|
||||
boolean included = false
|
||||
project.artifacts.values()*.rootElement*.process(project) {LayoutElement element ->
|
||||
if (element instanceof GwtCompilerOutputElement
|
||||
&& ((GwtCompilerOutputElement)element).findFacet(project) == gwtFacet) {
|
||||
included = true
|
||||
}
|
||||
return !(element instanceof ArtifactLayoutElement)
|
||||
}
|
||||
return included
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package org.jetbrains.jps.gwt
|
||||
|
||||
import org.jetbrains.jps.builders.ModuleBuilderService
|
||||
import org.jetbrains.jps.ProjectBuilder
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
class GwtModuleBuilderService extends ModuleBuilderService {
|
||||
@Override
|
||||
registerBuilders(ProjectBuilder builder) {
|
||||
builder.weavingBuilders << new GwtModuleBuilder()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package org.jetbrains.jps.gwt
|
||||
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
class GwtModuleUtil {
|
||||
public static boolean hasEntryPoints(File child) {
|
||||
try {
|
||||
def root = new XmlParser(false, false).parse(child)
|
||||
return !root."entry-point".isEmpty()
|
||||
}
|
||||
catch (IOException e) {
|
||||
return true;
|
||||
}
|
||||
catch (SAXParseException e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package org.jetbrains.jps.gwt;
|
||||
|
||||
import groovy.util.XmlParser;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class GwtModulesSearcher {
|
||||
private static final String GWT_XML_SUFFIX = ".gwt.xml";
|
||||
|
||||
public static List<String> findGwtModules(List<? extends CharSequence> sourcePaths) {
|
||||
final List<String> result = new ArrayList<String>();
|
||||
for (CharSequence sourcePath : sourcePaths) {
|
||||
collectGwtModules(new File(sourcePath.toString()), "", result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void collectGwtModules(File dir, String packageName, List<String> result) {
|
||||
if (!dir.isDirectory()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final File[] files = dir.listFiles();
|
||||
if (files != null) {
|
||||
for (File child : files) {
|
||||
final String name = child.getName();
|
||||
if (child.isFile() && name.endsWith(GWT_XML_SUFFIX)) {
|
||||
if (GwtModuleUtil.hasEntryPoints(child)) {
|
||||
result.add(packageName + name.substring(0, name.length() - GWT_XML_SUFFIX.length()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
collectGwtModules(child, packageName + name + ".", result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.0//EN"
|
||||
"http://google-web-toolkit.googlecode.com/svn/releases/2.0/distro-source/core/src/gwt-module.dtd">
|
||||
<module>
|
||||
<inherits name='com.google.gwt.user.User'/>
|
||||
<entry-point class='com.app.client.App'/>
|
||||
</module>
|
||||
@@ -1,5 +0,0 @@
|
||||
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.0//EN"
|
||||
"http://google-web-toolkit.googlecode.com/svn/releases/2.0/distro-source/core/src/gwt-module.dtd">
|
||||
<module>
|
||||
<inherits name='com.google.gwt.user.User'/>
|
||||
</modu>
|
||||
@@ -1,5 +0,0 @@
|
||||
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.0//EN"
|
||||
"http://google-web-toolkit.googlecode.com/svn/releases/2.0/distro-source/core/src/gwt-module.dtd">
|
||||
<module>
|
||||
<inherits name='com.google.gwt.user.User'/>
|
||||
</module>
|
||||
@@ -1,18 +0,0 @@
|
||||
package org.jetbrains.jps.gwt;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class GwtModulesSearcherTest extends TestCase {
|
||||
public void test() {
|
||||
List<String> modules = GwtModulesSearcher.findGwtModules(Arrays.asList("plugins/gwt/testData/modules"));
|
||||
assertEquals(new HashSet<String>(Arrays.asList("com.app.App", "com.app.InvalidXml")),
|
||||
new HashSet<String>(modules));
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Groovy" level="project" />
|
||||
<orderEntry type="module" module-name="jps" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
-1
@@ -1 +0,0 @@
|
||||
org.jetbrains.jps.jpa.JpaFacetDescriptorsElementType
|
||||
@@ -1 +0,0 @@
|
||||
org.jetbrains.jps.jpa.JpaFacetType
|
||||
@@ -1,10 +0,0 @@
|
||||
package org.jetbrains.jps.jpa
|
||||
|
||||
import org.jetbrains.jps.idea.Facet
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
class JpaFacet extends Facet {
|
||||
final List<String> descriptors = []
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package org.jetbrains.jps.jpa
|
||||
|
||||
import org.jetbrains.jps.Project
|
||||
import org.jetbrains.jps.artifacts.ComplexLayoutElement
|
||||
import org.jetbrains.jps.artifacts.FileCopyElement
|
||||
import org.jetbrains.jps.artifacts.LayoutElement
|
||||
import org.jetbrains.jps.artifacts.LayoutElementFactory
|
||||
import org.jetbrains.jps.idea.ProjectLoadingErrorReporter
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
class JpaFacetDescriptorsElement extends ComplexLayoutElement {
|
||||
String facetId
|
||||
ProjectLoadingErrorReporter errorReporter
|
||||
|
||||
List<LayoutElement> getSubstitution(Project project) {
|
||||
def moduleName = facetId.substring(0, facetId.indexOf('/'))
|
||||
def facet = project.modules[moduleName]?.facets[facetId]
|
||||
if (facet == null) {
|
||||
errorReporter.error("Unknown facet id: $facetId")
|
||||
}
|
||||
|
||||
if (!(facet instanceof JpaFacet)) {
|
||||
errorReporter.error("$facetId facet is not JPA facet")
|
||||
}
|
||||
|
||||
List<LayoutElement> result = []
|
||||
facet.descriptors.each {String path ->
|
||||
result << LayoutElementFactory.createParentDirectories("META-INF", new FileCopyElement(filePath: path))
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package org.jetbrains.jps.jpa
|
||||
|
||||
import org.jetbrains.jps.MacroExpander
|
||||
import org.jetbrains.jps.Project
|
||||
import org.jetbrains.jps.artifacts.LayoutElement
|
||||
import org.jetbrains.jps.artifacts.LayoutElementTypeService
|
||||
import org.jetbrains.jps.idea.ProjectLoadingErrorReporter
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
class JpaFacetDescriptorsElementType extends LayoutElementTypeService {
|
||||
JpaFacetDescriptorsElementType() {
|
||||
super("jpa-descriptors")
|
||||
}
|
||||
|
||||
@Override
|
||||
LayoutElement createElement(Project project, Node tag, MacroExpander macroExpander, ProjectLoadingErrorReporter errorReporter) {
|
||||
return new JpaFacetDescriptorsElement(facetId: tag."@facet", errorReporter: errorReporter)
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package org.jetbrains.jps.jpa
|
||||
|
||||
import org.jetbrains.jps.idea.FacetTypeService
|
||||
import org.jetbrains.jps.idea.Facet
|
||||
import org.jetbrains.jps.Module
|
||||
import org.jetbrains.jps.MacroExpander
|
||||
|
||||
import org.jetbrains.jps.idea.IdeaProjectLoadingUtil
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
class JpaFacetType extends FacetTypeService {
|
||||
JpaFacetType() {
|
||||
super("jpa")
|
||||
}
|
||||
|
||||
@Override
|
||||
Facet createFacet(Module module, String name, Node facetConfiguration, MacroExpander macroExpander) {
|
||||
JpaFacet facet = new JpaFacet(name: name)
|
||||
facetConfiguration?.deploymentDescriptor?.each {Node tag ->
|
||||
String path = macroExpander.expandMacros(IdeaProjectLoadingUtil.pathFromUrl(tag."@url"))
|
||||
facet.descriptors << path
|
||||
}
|
||||
return facet
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="jpa" name="JPA">
|
||||
<configuration>
|
||||
<setting name="validation-enabled" value="true" />
|
||||
<setting name="provider-name" value="" />
|
||||
<datasource-mapping>
|
||||
<factory-entry name="NewPersistenceUnit" />
|
||||
</datasource-mapping>
|
||||
<deploymentDescriptor name="persistence.xml" url="file://$MODULE_DIR$/src/META-INF/persistence.xml" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ArtifactManager">
|
||||
<artifact type="exploded-war" name="jpaTest">
|
||||
<output-path>$PROJECT_DIR$/out/artifacts/jpaTest</output-path>
|
||||
<root id="root">
|
||||
<element id="directory" name="WEB-INF">
|
||||
<element id="directory" name="classes">
|
||||
<element id="jpa-descriptors" facet="jpaTest/jpa/JPA" />
|
||||
</element>
|
||||
</element>
|
||||
</root>
|
||||
</artifact>
|
||||
</component>
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/jpaTest.iml" filepath="$PROJECT_DIR$/jpaTest.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_5" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
|
||||
|
||||
<persistence-unit name="NewPersistenceUnit"/>
|
||||
</persistence>
|
||||
@@ -1,29 +0,0 @@
|
||||
package org.jetbrains.jps
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
class JpaTest extends JpsBuildTestCase {
|
||||
public void testOverwriteArtifacts() throws Exception {
|
||||
doTest("plugins/jpa/testData/jpaTest/jpaTest.ipr", null, {
|
||||
dir("artifacts") {
|
||||
dir("jpaTest") {
|
||||
dir("WEB-INF") {
|
||||
dir("classes") {
|
||||
dir("META-INF") {
|
||||
file("persistence.xml")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dir("production") {
|
||||
dir("jpaTest") {
|
||||
dir("META-INF") {
|
||||
file("persistence.xml")
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -100,4 +100,8 @@ public class CompletionParameters {
|
||||
public boolean isRelaxedMatching() {
|
||||
return myRelaxedMatching;
|
||||
}
|
||||
|
||||
public CompletionParameters withPosition(PsiElement element, int offset) {
|
||||
return new CompletionParameters(element, myOriginalFile, myCompletionType, offset, myInvocationCount, myLookup, myRelaxedMatching);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,4 +167,10 @@ public class LookupElementPresentation {
|
||||
public void setTypeGrayed(boolean typeGrayed) {
|
||||
myTypeGrayed = typeGrayed;
|
||||
}
|
||||
|
||||
public static LookupElementPresentation renderElement(LookupElement element) {
|
||||
LookupElementPresentation presentation = new LookupElementPresentation();
|
||||
element.renderElement(presentation);
|
||||
return presentation;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
import java.util.List;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.Manifest;
|
||||
@@ -147,32 +148,13 @@ public class JdkUtil {
|
||||
commandLine.setExePath(exePath);
|
||||
|
||||
ParametersList parametersList = javaParameters.getVMParametersList();
|
||||
commandLine.addParameters(parametersList.getList());
|
||||
|
||||
// Value of -Dfile.encoding and charset of GeneralCommandLine should be in sync in order process's input and output be correctly handled.
|
||||
String encoding = parametersList.getPropertyValue("file.encoding");
|
||||
if (encoding == null) {
|
||||
Charset charset = javaParameters.getCharset();
|
||||
if (charset == null) charset = EncodingManager.getInstance().getDefaultCharset();
|
||||
if (charset == null) charset = CharsetToolkit.getDefaultSystemCharset();
|
||||
commandLine.addParameter("-Dfile.encoding=" + charset.name());
|
||||
commandLine.setCharset(charset);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
Charset charset = Charset.forName(encoding);
|
||||
commandLine.setCharset(charset);
|
||||
}
|
||||
catch (UnsupportedCharsetException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
commandLine.setEnvParams(javaParameters.getEnv());
|
||||
commandLine.setPassParentEnvs(javaParameters.isPassParentEnvs());
|
||||
|
||||
final Class commandLineWrapper;
|
||||
if (forceDynamicClasspath && (commandLineWrapper = getCommandLineWrapperClass()) != null) {
|
||||
File classpathFile = null;
|
||||
File vmParamsFile = null;
|
||||
if(!parametersList.hasParameter("-classpath") && !parametersList.hasParameter("-cp")){
|
||||
try {
|
||||
classpathFile = FileUtil.createTempFile("classpath", null);
|
||||
@@ -199,16 +181,55 @@ public class JdkUtil {
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
|
||||
try {
|
||||
vmParamsFile = FileUtil.createTempFile("vm_params", null);
|
||||
final PrintWriter writer = new PrintWriter(vmParamsFile);
|
||||
try {
|
||||
for (String param : parametersList.getList()) {
|
||||
if (param.startsWith("-D")) {
|
||||
writer.println(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
final List<String> list = parametersList.getList();
|
||||
if (vmParamsFile == null) {
|
||||
commandLine.addParameters(list);
|
||||
} else {
|
||||
for (String param : list) {
|
||||
if (!param.trim().startsWith("-D")) {
|
||||
commandLine.addParameter(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
appendEncoding(javaParameters, commandLine, parametersList);
|
||||
if (classpathFile != null) {
|
||||
commandLine.addParameter(commandLineWrapper.getName());
|
||||
commandLine.addParameter(classpathFile.getAbsolutePath());
|
||||
}
|
||||
if (vmParamsFile != null) {
|
||||
commandLine.addParameter("@vm_params");
|
||||
commandLine.addParameter(vmParamsFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
else if(!parametersList.hasParameter("-classpath") && !parametersList.hasParameter("-cp")){
|
||||
else if (!parametersList.hasParameter("-classpath") && !parametersList.hasParameter("-cp")){
|
||||
commandLine.addParameters(parametersList.getList());
|
||||
appendEncoding(javaParameters, commandLine, parametersList);
|
||||
|
||||
commandLine.addParameter("-classpath");
|
||||
commandLine.addParameter(javaParameters.getClassPath().getPathsString());
|
||||
} else {
|
||||
commandLine.addParameters(parametersList.getList());
|
||||
appendEncoding(javaParameters, commandLine, parametersList);
|
||||
}
|
||||
|
||||
final String mainClass = javaParameters.getMainClass();
|
||||
@@ -220,6 +241,26 @@ public class JdkUtil {
|
||||
return commandLine;
|
||||
}
|
||||
|
||||
private static void appendEncoding(SimpleJavaParameters javaParameters, GeneralCommandLine commandLine, ParametersList parametersList) {
|
||||
// Value of -Dfile.encoding and charset of GeneralCommandLine should be in sync in order process's input and output be correctly handled.
|
||||
String encoding = parametersList.getPropertyValue("file.encoding");
|
||||
if (encoding == null) {
|
||||
Charset charset = javaParameters.getCharset();
|
||||
if (charset == null) charset = EncodingManager.getInstance().getDefaultCharset();
|
||||
if (charset == null) charset = CharsetToolkit.getDefaultSystemCharset();
|
||||
commandLine.addParameter("-Dfile.encoding=" + charset.name());
|
||||
commandLine.setCharset(charset);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
Charset charset = Charset.forName(encoding);
|
||||
commandLine.setCharset(charset);
|
||||
}
|
||||
catch (UnsupportedCharsetException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Class getCommandLineWrapperClass() {
|
||||
try {
|
||||
|
||||
@@ -617,6 +617,7 @@ public abstract class LogConsoleBase extends AdditionalTabComponent implements L
|
||||
myAlarm.addRequest(this, 100);
|
||||
}
|
||||
};
|
||||
if (myAlarm.isDisposed()) return;
|
||||
myAlarm.addRequest(runnable, 10);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,11 +24,6 @@ public class IndentInfo {
|
||||
private final int mySpaces;
|
||||
private final int myIndentSpaces;
|
||||
private final int myLineFeeds;
|
||||
//
|
||||
// The flag is used for compatibility with older versions of Intellij IDEA where spaces could be replaced with tabs inside a line of code,
|
||||
// not only in the beginning of the line.
|
||||
//
|
||||
private static boolean myInlineTabsEnabled = "true".equalsIgnoreCase(System.getProperty("enable.inline.tabs"));
|
||||
|
||||
/** @see WhiteSpace#setForceSkipTabulationsUsage(boolean) */
|
||||
private boolean myForceSkipTabulationsUsage;
|
||||
@@ -63,45 +58,38 @@ public class IndentInfo {
|
||||
|
||||
if (options.USE_TAB_CHARACTER && !myForceSkipTabulationsUsage) {
|
||||
if (options.SMART_TABS) {
|
||||
return fillUsingSmartTabs(buffer, options);
|
||||
}
|
||||
else if (myLineFeeds > 0 || myInlineTabsEnabled) {
|
||||
return fillUsingTabs(buffer, options);
|
||||
}
|
||||
}
|
||||
int spaces = getTotalSpaces();
|
||||
if (spaces > 0) {
|
||||
StringUtil.repeatSymbol(buffer, ' ', spaces);
|
||||
}
|
||||
return buffer.toString();
|
||||
|
||||
}
|
||||
|
||||
private String fillUsingTabs(StringBuffer buffer, CommonCodeStyleSettings.IndentOptions options) {
|
||||
int size = getTotalSpaces();
|
||||
while (size > 0) {
|
||||
if (size >= options.TAB_SIZE) {
|
||||
buffer.append('\t');
|
||||
size -= options.TAB_SIZE;
|
||||
int tabCount = myIndentSpaces / options.TAB_SIZE;
|
||||
int leftSpaces = myIndentSpaces - tabCount * options.TAB_SIZE;
|
||||
if (tabCount > 0) {
|
||||
StringUtil.repeatSymbol(buffer, '\t', tabCount);
|
||||
}
|
||||
if (leftSpaces + mySpaces > 0) {
|
||||
StringUtil.repeatSymbol(buffer, ' ', leftSpaces + mySpaces);
|
||||
}
|
||||
}
|
||||
else {
|
||||
buffer.append(' ');
|
||||
size--;
|
||||
int size = getTotalSpaces();
|
||||
while (size > 0) {
|
||||
if (size >= options.TAB_SIZE) {
|
||||
buffer.append('\t');
|
||||
size -= options.TAB_SIZE;
|
||||
}
|
||||
else {
|
||||
buffer.append(' ');
|
||||
size--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
int spaces = getTotalSpaces();
|
||||
if (spaces > 0) {
|
||||
StringUtil.repeatSymbol(buffer, ' ', spaces);
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private String fillUsingSmartTabs(StringBuffer buffer, CommonCodeStyleSettings.IndentOptions options) {
|
||||
int tabCount = myIndentSpaces / options.TAB_SIZE;
|
||||
int leftSpaces = myIndentSpaces - tabCount * options.TAB_SIZE;
|
||||
if (tabCount > 0) {
|
||||
StringUtil.repeatSymbol(buffer, '\t', tabCount);
|
||||
}
|
||||
if (leftSpaces + mySpaces > 0) {
|
||||
StringUtil.repeatSymbol(buffer, ' ', leftSpaces + mySpaces);
|
||||
}
|
||||
return buffer.toString();
|
||||
|
||||
}
|
||||
|
||||
public int getTotalSpaces() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,8 @@
|
||||
package com.intellij.ide;
|
||||
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.intellij.execution.util.ExecUtil;
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -42,6 +44,7 @@ import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
@@ -58,20 +61,19 @@ public class BrowserUtil {
|
||||
// We have to violate the RFC since we need to distinguish
|
||||
// real schemes from local Windows paths; The only difference
|
||||
// with RFC is that we do not allow schemes with length=1 (in other case
|
||||
// local paths like "C:/temp/index.html" whould be erroneously interpreted as
|
||||
// local paths like "C:/temp/index.html" would be erroneously interpreted as
|
||||
// external URLs.)
|
||||
@NonNls private static final Pattern ourExternalPrefix = Pattern.compile("^[\\w\\+\\.\\-]{2,}:");
|
||||
private static final Pattern ourAnchorsuffix = Pattern.compile("#(.*)$");
|
||||
private static final Pattern ourExternalPrefix = Pattern.compile("^[\\w\\+\\.\\-]{2,}:");
|
||||
private static final Pattern ourAnchorSuffix = Pattern.compile("#(.*)$");
|
||||
|
||||
private BrowserUtil() {
|
||||
}
|
||||
private BrowserUtil() { }
|
||||
|
||||
public static boolean isAbsoluteURL(String url) {
|
||||
return ourExternalPrefix.matcher(url.toLowerCase()).find();
|
||||
}
|
||||
|
||||
public static String getDocURL(String url) {
|
||||
Matcher anchorMatcher = ourAnchorsuffix.matcher(url);
|
||||
Matcher anchorMatcher = ourAnchorSuffix.matcher(url);
|
||||
|
||||
if (anchorMatcher.find()) {
|
||||
return anchorMatcher.reset().replaceAll("");
|
||||
@@ -81,7 +83,7 @@ public class BrowserUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static URL getURL(String url) throws java.net.MalformedURLException {
|
||||
public static URL getURL(String url) throws MalformedURLException {
|
||||
if (!isAbsoluteURL(url)) {
|
||||
return new URL("file", "", url);
|
||||
}
|
||||
@@ -89,128 +91,95 @@ public class BrowserUtil {
|
||||
return VfsUtil.convertToURL(url);
|
||||
}
|
||||
|
||||
private static void launchBrowser(final String url, String[] command) {
|
||||
try {
|
||||
URL curl = getURL(url);
|
||||
/**
|
||||
* Main method: tries to launch a browser using every possible way.
|
||||
*
|
||||
* @param url an URL to open.
|
||||
*/
|
||||
public static void launchBrowser(@NonNls String url) {
|
||||
LOG.debug("Launch browser: " + url);
|
||||
|
||||
if (curl != null) {
|
||||
final String urlString = curl.toString();
|
||||
String[] commandLine;
|
||||
if (SystemInfo.isWindows && isUseDefaultBrowser()) {
|
||||
commandLine = new String[command.length + 2];
|
||||
System.arraycopy(command, 0, commandLine, 0, command.length);
|
||||
commandLine[commandLine.length - 2] = "\"\"";
|
||||
commandLine[commandLine.length - 1] = "\"" + redirectUrl(url, urlString) + "\"";
|
||||
}
|
||||
else {
|
||||
commandLine = new String[command.length + 1];
|
||||
System.arraycopy(command, 0, commandLine, 0, command.length);
|
||||
commandLine[commandLine.length - 1] = SystemInfo.isMac && isUseDefaultBrowser() ? escapeUrl(redirectUrl(url, urlString))
|
||||
: escapeUrl(urlString);
|
||||
}
|
||||
Runtime.getRuntime().exec(commandLine);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Browser launched with command line: " + Arrays.toString(commandLine));
|
||||
}
|
||||
if (url.startsWith("jar:")) {
|
||||
url = extractFiles(url);
|
||||
if (url == null) return;
|
||||
}
|
||||
|
||||
if (getGeneralSettingsInstance().isUseDefaultBrowser() && canStartDefaultBrowser()) {
|
||||
final String[] command = getDefaultBrowserCommand();
|
||||
if (command != null) {
|
||||
launchBrowserByCommand(url, command);
|
||||
}
|
||||
else {
|
||||
showErrorMessage(IdeBundle.message("error.malformed.url", url), CommonBundle.getErrorTitle());
|
||||
launchBrowserUsingDesktopApi(url);
|
||||
}
|
||||
}
|
||||
catch (final IOException e) {
|
||||
showErrorMessage(IdeBundle.message("error.cannot.start.browser", e.getMessage()),
|
||||
CommonBundle.getErrorTitle());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method works around Windows 'start' command behaivor of dropping anchors from the url for local urls.
|
||||
*/
|
||||
private static String redirectUrl(String url, @NonNls String urlString) throws IOException {
|
||||
if (url.indexOf('&') == -1 && (!urlString.startsWith("file:") || urlString.indexOf("#") == -1)) return urlString;
|
||||
|
||||
File redirect = FileUtil.createTempFile("redirect", ".html");
|
||||
redirect.deleteOnExit();
|
||||
FileWriter writer = new FileWriter(redirect);
|
||||
writer.write("<html><head></head><body><script type=\"text/javascript\">window.location=\"" + url + "\";</script></body></html>");
|
||||
writer.close();
|
||||
return VfsUtil.pathToUrl(redirect.getAbsolutePath());
|
||||
}
|
||||
|
||||
private static boolean isUseDefaultBrowser() {
|
||||
Application application = ApplicationManager.getApplication();
|
||||
if (application == null) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return getGeneralSettingsInstance().isUseDefaultBrowser();
|
||||
launchBrowserUsingStandardWay(url);
|
||||
}
|
||||
}
|
||||
|
||||
private static void showErrorMessage(final String message, final String title) {
|
||||
final Application app = ApplicationManager.getApplication();
|
||||
if (app == null) {
|
||||
return; // Not started yet. Not able to show message up. (Could happen in License panel under Linux).
|
||||
}
|
||||
|
||||
Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
Messages.showMessageDialog(message,
|
||||
title,
|
||||
Messages.getErrorIcon());
|
||||
}
|
||||
};
|
||||
|
||||
if (app.isDispatchThread()) {
|
||||
runnable.run();
|
||||
}
|
||||
else {
|
||||
app.invokeLater(runnable, ModalityState.NON_MODAL);
|
||||
}
|
||||
}
|
||||
|
||||
private static void launchBrowserUsingStandardWay(final String url) {
|
||||
String[] command;
|
||||
try {
|
||||
String browserPath = getGeneralSettingsInstance().getBrowserPath();
|
||||
if (browserPath == null || browserPath.trim().length() == 0) {
|
||||
showErrorMessage(IdeBundle.message("error.please.specify.path.to.web.browser"),
|
||||
IdeBundle.message("title.browser.not.found"));
|
||||
return;
|
||||
}
|
||||
|
||||
command = getOpenBrowserCommand(browserPath);
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
// todo: fix the possible problem on startup, see SCR #35066
|
||||
command = getDefaultBrowserCommand();
|
||||
if (command == null) {
|
||||
showErrorMessage(IdeBundle.message("error.please.open.url.manually", url, ApplicationNamesInfo.getInstance().getProductName()),
|
||||
IdeBundle.message("title.browser.path.not.found"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
// We do not need to check browserPath under Win32
|
||||
|
||||
launchBrowser(url, command);
|
||||
}
|
||||
|
||||
private static GeneralSettings getGeneralSettingsInstance() {
|
||||
final GeneralSettings settings = GeneralSettings.getInstance();
|
||||
if (settings != null) return settings;
|
||||
return new GeneralSettings();
|
||||
final GeneralSettings settings = ApplicationManager.getApplication() != null ? GeneralSettings.getInstance() : null;
|
||||
return settings != null ? settings : new GeneralSettings();
|
||||
}
|
||||
|
||||
private static boolean launchDefaultBrowserUsingJdk6Api(String sUrl) {
|
||||
try {
|
||||
URL url = getURL(sUrl);
|
||||
if (url == null) return false;
|
||||
Desktop.getDesktop().browse(url.toURI());
|
||||
LOG.debug("Browser launched using JDK 1.6 API");
|
||||
public static boolean canStartDefaultBrowser() {
|
||||
if (SystemInfo.isMac || SystemInfo.isWindows) {
|
||||
return true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
return false;
|
||||
else if (SystemInfo.isUnix && SystemInfo.hasXdgOpen) {
|
||||
return true;
|
||||
}
|
||||
else if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNls
|
||||
private static String[] getDefaultBrowserCommand() {
|
||||
if (SystemInfo.isWindows9x) {
|
||||
return new String[]{"command.com", "/c", "start"};
|
||||
}
|
||||
else if (SystemInfo.isWindows) {
|
||||
return new String[]{"cmd.exe", "/c", "start"};
|
||||
}
|
||||
else if (SystemInfo.isMac) {
|
||||
return new String[]{ExecUtil.getOpenCommandPath()};
|
||||
}
|
||||
else if (SystemInfo.isUnix && SystemInfo.hasXdgOpen) {
|
||||
return new String[]{"xdg-open"};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void launchBrowserByCommand(final String url, @NotNull final String[] command) {
|
||||
URL curl;
|
||||
try {
|
||||
curl = getURL(url);
|
||||
}
|
||||
catch (MalformedURLException ignored) {
|
||||
curl = null;
|
||||
}
|
||||
if (curl == null) {
|
||||
showErrorMessage(IdeBundle.message("error.malformed.url", url), CommonBundle.getErrorTitle());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final GeneralCommandLine commandLine = new GeneralCommandLine(command);
|
||||
commandLine.addParameter(curl.toString());
|
||||
commandLine.createProcess();
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Browser launched with command line: " + commandLine.getCommandLineString());
|
||||
}
|
||||
}
|
||||
catch (final ExecutionException e) {
|
||||
showErrorMessage(IdeBundle.message("error.cannot.start.browser", e.getMessage()), CommonBundle.getErrorTitle());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,6 +193,84 @@ public class BrowserUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean launchBrowserUsingDesktopApi(final String sUrl) {
|
||||
try {
|
||||
URL url = getURL(sUrl);
|
||||
if (url == null) return false;
|
||||
Desktop.getDesktop().browse(url.toURI());
|
||||
LOG.debug("Browser launched using JDK 1.6 API");
|
||||
return true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void launchBrowserUsingStandardWay(final String url) {
|
||||
String browserPath = getGeneralSettingsInstance().getBrowserPath();
|
||||
if (StringUtil.isEmptyOrSpaces(browserPath)) {
|
||||
showErrorMessage(IdeBundle.message("error.please.specify.path.to.web.browser"), IdeBundle.message("title.browser.not.found"));
|
||||
return;
|
||||
}
|
||||
|
||||
launchBrowserByCommand(url, getOpenBrowserCommand(browserPath));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #getOpenBrowserCommand(String)} instead
|
||||
*/
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public static String[] getOpenBrowserCommand(final @NonNls @NotNull String browserPath, final String... parameters) {
|
||||
return getOpenBrowserCommand(browserPath);
|
||||
}
|
||||
|
||||
public static String[] getOpenBrowserCommand(final @NonNls @NotNull String browserPath) {
|
||||
final String[] command;
|
||||
if (SystemInfo.isMac) {
|
||||
if (new File(browserPath).isFile()) {
|
||||
// versions before 10.6 don't allow to pass command line arguments to browser via 'open' command
|
||||
// so we use full path to browser executable in such case
|
||||
command = new String[] {browserPath};
|
||||
}
|
||||
else {
|
||||
command = new String[]{ExecUtil.getOpenCommandPath(), "-a", browserPath};
|
||||
}
|
||||
}
|
||||
else if (SystemInfo.isWindows) {
|
||||
if (new File(browserPath).isFile()) {
|
||||
command = new String[]{browserPath};
|
||||
}
|
||||
else {
|
||||
command = new String[]{SystemInfo.isWindows9x ? "command.com" : "cmd.exe", "/c", "start", browserPath};
|
||||
}
|
||||
}
|
||||
else {
|
||||
command = new String[]{browserPath};
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
private static void showErrorMessage(final String message, final String title) {
|
||||
final Application app = ApplicationManager.getApplication();
|
||||
if (app == null) {
|
||||
return; // Not started yet. Not able to show message up. (Could happen in License panel under Linux).
|
||||
}
|
||||
|
||||
Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
Messages.showMessageDialog(message, title, Messages.getErrorIcon());
|
||||
}
|
||||
};
|
||||
|
||||
if (app.isDispatchThread()) {
|
||||
runnable.run();
|
||||
}
|
||||
else {
|
||||
app.invokeLater(runnable, ModalityState.NON_MODAL);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String extractFiles(String url) {
|
||||
try {
|
||||
int sharpPos = url.indexOf('#');
|
||||
@@ -350,100 +397,10 @@ public class BrowserUtil {
|
||||
return new File(PathManager.getSystemPath(), "ExtractedFiles");
|
||||
}
|
||||
|
||||
public static void launchBrowser(@NonNls String url) {
|
||||
LOG.debug("Launch browser: " + url);
|
||||
if (url.startsWith("jar:")) {
|
||||
url = extractFiles(url);
|
||||
if (url == null) return;
|
||||
}
|
||||
if (canStartDefaultBrowser() && isUseDefaultBrowser()) {
|
||||
if (SystemInfo.isLinux && launchDefaultBrowserUsingJdk6Api(url)) {
|
||||
return;
|
||||
}
|
||||
|
||||
launchBrowser(url, getDefaultBrowserCommand());
|
||||
}
|
||||
else {
|
||||
launchBrowserUsingStandardWay(url);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNls
|
||||
private static String[] getDefaultBrowserCommand() {
|
||||
if (SystemInfo.isWindows9x) {
|
||||
return new String[]{"command.com", "/c", "start"};
|
||||
}
|
||||
else if (SystemInfo.isWindows) {
|
||||
return new String[]{"cmd.exe", "/c", "start"};
|
||||
}
|
||||
else if (SystemInfo.isMac) {
|
||||
return new String[]{ExecUtil.getOpenCommandPath()};
|
||||
}
|
||||
else if (SystemInfo.isUnix) {
|
||||
return new String[]{"mozilla"};
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean canStartDefaultBrowser() {
|
||||
if (SystemInfo.isMac || SystemInfo.isWindows) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SystemInfo.isLinux && Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isOpenCommandSupportArgs() {
|
||||
return SystemInfo.isMacOSSnowLeopard;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #getOpenBrowserCommand(String)} instead
|
||||
*/
|
||||
public static String[] getOpenBrowserCommand(final @NonNls @NotNull String browserPath, final String... parameters) {
|
||||
return getOpenBrowserCommand(browserPath);
|
||||
}
|
||||
|
||||
public static String[] getOpenBrowserCommand(final @NonNls @NotNull String browserPath) {
|
||||
String[] command;
|
||||
if (SystemInfo.isMac) {
|
||||
File browserExecutable = new File(browserPath);
|
||||
if (browserExecutable.isFile()) {
|
||||
//versions before 10.6 don't allow to pass command line arguments to browser via 'open' command so we use full path to browser executable in such cases
|
||||
command = new String[] {browserPath};
|
||||
}
|
||||
else {
|
||||
command = new String[]{ExecUtil.getOpenCommandPath(), "-a", browserPath};
|
||||
}
|
||||
}
|
||||
else if (SystemInfo.isWindows9x) {
|
||||
if (browserPath.indexOf(File.separatorChar) != -1) {
|
||||
command = new String[]{browserPath};
|
||||
}
|
||||
else {
|
||||
command = new String[]{"command.com", "/c", "start", browserPath};
|
||||
}
|
||||
}
|
||||
else if (SystemInfo.isWindows) {
|
||||
if (browserPath.indexOf(File.separatorChar) != -1) {
|
||||
command = new String[]{browserPath};
|
||||
}
|
||||
else {
|
||||
command = new String[]{"cmd.exe", "/c", "start", browserPath};
|
||||
}
|
||||
}
|
||||
else {
|
||||
command = new String[]{browserPath};
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
private static class ConfirmExtractDialog extends OptionsDialog {
|
||||
private ConfirmExtractDialog() {
|
||||
super(null);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package com.intellij.util.ui;
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
@@ -50,7 +51,7 @@ public abstract class OptionsDialog extends DialogWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
protected OptionsDialog(Project project) {
|
||||
protected OptionsDialog(@Nullable Project project) {
|
||||
super(project, true);
|
||||
myProject = project;
|
||||
setDoNotAskOption(new MyDoNotAsk());
|
||||
|
||||
+5
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.openapi.vfs.newvfs.persistent;
|
||||
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.ManagingFS;
|
||||
@@ -122,8 +123,10 @@ public class RefreshWorker {
|
||||
else {
|
||||
long currentTimestamp = persistence.getTimeStamp(file);
|
||||
long upToDateTimestamp = delegate.getTimeStamp(file);
|
||||
long currentLength = SystemInfo.isUnix ? persistence.getLength(file) : -1;
|
||||
long upToDateLength = SystemInfo.isUnix ? delegate.getLength(file) : -1;
|
||||
|
||||
if (currentTimestamp != upToDateTimestamp) {
|
||||
if (currentTimestamp != upToDateTimestamp || currentLength != upToDateLength) {
|
||||
scheduleUpdateContent(file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import com.intellij.openapi.project.DumbAwareRunnable;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.startup.StartupManager;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.popup.Balloon;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
@@ -2186,6 +2187,9 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
if (root != null) {
|
||||
JComponent toFocus = IdeFocusTraversalPolicy.getPreferredFocusedComponent(root);
|
||||
if (toFocus != null) {
|
||||
if (DialogWrapper.findInstance(toFocus) != null) {
|
||||
return new ActionCallback.Done(); //IDEA-80929
|
||||
}
|
||||
return IdeFocusManager.findInstanceByComponent(toFocus).requestFocus(toFocus, forced);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ error.malformed.url=Malformed url: {0}
|
||||
error.cannot.start.browser=Cannot start browser: {0}
|
||||
error.please.specify.path.to.web.browser=Please specify a path to web browser in File | Settings | Web Browsers
|
||||
title.browser.not.found=Browser Not Found
|
||||
error.please.open.url.manually=Please open URL ({0}) manually. {1} can''t open it in browser
|
||||
title.browser.path.not.found=Browser Path Not Found
|
||||
action.sort.alphabetically=Sort Alphabetically
|
||||
button.finish=&Finish
|
||||
|
||||
@@ -443,7 +443,6 @@
|
||||
<completion.skip implementation="com.intellij.codeInsight.template.impl.LiveTemplateCompletionContributor$Skipper" id="skipLiveTemplate"/>
|
||||
|
||||
<completion.contributor language="TEXT" implementationClass="com.intellij.openapi.vcs.CommitCompletionContributor" id="commitCompletion" order="first, before liveTemplates"/>
|
||||
<completion.contributor language="JAVA" implementationClass="com.intellij.codeInspection.magicConstant.MagicCompletionContributor" id="magicCompletion" order="first, before liveTemplates"/>
|
||||
|
||||
<applicationService serviceInterface="com.intellij.execution.console.ConsoleFoldingSettings" serviceImplementation="com.intellij.execution.console.ConsoleFoldingSettings"/>
|
||||
<console.folding implementation="com.intellij.execution.console.SubstringConsoleFolding"/>
|
||||
@@ -653,7 +652,7 @@
|
||||
<fileIconProvider implementation="com.intellij.ide.FileIconPatcherImpl"/>
|
||||
<renameHandler implementation="com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler"/>
|
||||
<renameHandler implementation="com.intellij.refactoring.rename.inplace.MemberInplaceRenameHandler"/>
|
||||
<completion.contributor language="any" implementationClass="com.intellij.refactoring.rename.inplace.CompletionContributorForInplaceRename" order="first"/>
|
||||
<completion.contributor language="any" implementationClass="com.intellij.refactoring.rename.inplace.CompletionContributorForInplaceRename" order="first, before liveTemplates"/>
|
||||
|
||||
<projectService serviceInterface="com.intellij.openapi.vcs.changes.ui.ChangesFileNameDecorator"
|
||||
serviceImplementation="com.intellij.openapi.vcs.changes.ui.WolfChangesFileNameDecorator"/>
|
||||
@@ -698,7 +697,6 @@
|
||||
serviceImplementation="com.intellij.openapi.vcs.impl.CodeSmellDetectorImpl"/>
|
||||
|
||||
<editorTabTitleProvider implementation="com.intellij.openapi.fileEditor.impl.UniqueNameEditorTabTitleProvider"/>
|
||||
<applicationService serviceImplementation="com.intellij.execution.JavaRunConfigurationExtensionManager"/>
|
||||
|
||||
<projectService serviceInterface="com.intellij.psi.util.PsiModificationTracker"
|
||||
serviceImplementation="com.intellij.psi.impl.PsiModificationTrackerImpl"/>
|
||||
|
||||
@@ -102,10 +102,12 @@
|
||||
<injection language="HQL" injector-id="java">
|
||||
<display-name>Session.createQuery (org.hibernate)</display-name>
|
||||
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("createQuery").withParameters("java.lang.String").definedInClass("org.hibernate.Session"))]]></place>
|
||||
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("createQuery").withParameters("java.lang.String").definedInClass("org.hibernate.SharedSessionContract"))]]></place>
|
||||
</injection>
|
||||
<injection language="SQL" injector-id="java">
|
||||
<display-name>Session.createSQLQuery (org.hibernate)</display-name>
|
||||
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("createSQLQuery").withParameters("java.lang.String").definedInClass("org.hibernate.Session"))]]></place>
|
||||
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("createSQLQuery").withParameters("java.lang.String").definedInClass("org.hibernate.SharedSessionContract"))]]></place>
|
||||
</injection>
|
||||
|
||||
<injection language="SQL" injector-id="java">
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module-library" exported="">
|
||||
<library>
|
||||
<library name="android-sdk-tools-jps">
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/../lib/sdklib.jar!/" />
|
||||
</CLASSES>
|
||||
|
||||
+110
-87
@@ -45,6 +45,7 @@ import com.intellij.util.PairConsumer;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.GroovyBundle;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
@@ -64,18 +65,18 @@ import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatem
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
|
||||
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.util.GroovyPropertyUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.DefaultGroovyVariableNameValidator;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.inline.InlineMethodConflictSolver;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
import static com.intellij.patterns.PsiJavaPatterns.elementType;
|
||||
import static com.intellij.util.containers.CollectionFactory.arrayList;
|
||||
import static com.intellij.util.containers.CollectionFactory.hashMap;
|
||||
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*;
|
||||
import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.SEPARATORS;
|
||||
@@ -176,18 +177,20 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
|
||||
|
||||
private static void addAllClasses(CompletionParameters parameters, final CompletionResultSet result, final InheritorsHolder inheritors) {
|
||||
addAllClasses(parameters, result, new Consumer<LookupElement>() {
|
||||
addAllClasses(parameters, new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement element) {
|
||||
result.addElement(element);
|
||||
}
|
||||
}, inheritors);
|
||||
}, inheritors, result.getPrefixMatcher());
|
||||
}
|
||||
|
||||
public static void addAllClasses(CompletionParameters parameters, CompletionResultSet result, final Consumer<LookupElement> consumer, final InheritorsHolder inheritors) {
|
||||
public static void addAllClasses(CompletionParameters parameters,
|
||||
final Consumer<LookupElement> consumer,
|
||||
final InheritorsHolder inheritors, final PrefixMatcher matcher) {
|
||||
final PsiElement position = parameters.getPosition();
|
||||
final ElementFilter filter = getClassFilter(position);
|
||||
AllClassesGetter.processJavaClasses(parameters, result.getPrefixMatcher(), parameters.getInvocationCount() <= 1,
|
||||
AllClassesGetter.processJavaClasses(parameters, matcher, parameters.getInvocationCount() <= 1,
|
||||
new Consumer<PsiClass>() {
|
||||
@Override
|
||||
public void consume(PsiClass psiClass) {
|
||||
@@ -310,21 +313,21 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
|
||||
addUnfinishedMethodTypeParameters(position, result);
|
||||
|
||||
final PsiElement parent = position.getParent();
|
||||
GrReferenceElement reference;
|
||||
if (parent instanceof GrReferenceElement) {
|
||||
reference = (GrReferenceElement)parent;
|
||||
if (reference.getParent() instanceof GrImportStatement && reference.getQualifier() != null) {
|
||||
result.addElement(LookupElementBuilder.create("*"));
|
||||
}
|
||||
} else if (couldContainReference(position)) {
|
||||
reference = GroovyPsiElementFactory.getInstance(position.getProject()).createReferenceElementFromText("Foo", position);
|
||||
} else {
|
||||
GrReferenceElement reference = findGroovyReference(position);
|
||||
if (reference == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (reference.getParent() instanceof GrImportStatement && reference.getQualifier() != null) {
|
||||
result.addElement(LookupElementBuilder.create("*"));
|
||||
}
|
||||
|
||||
InheritorsHolder inheritors = new InheritorsHolder(position, result);
|
||||
completeReference(parameters, result, reference, inheritors);
|
||||
if (GroovySmartCompletionContributor.AFTER_NEW.accepts(position)) {
|
||||
GroovySmartCompletionContributor.generateInheritorVariants(parameters, result.getPrefixMatcher(), inheritors);
|
||||
}
|
||||
|
||||
result.addAllElements(completeReference(parameters, reference, inheritors, result.getPrefixMatcher()));
|
||||
|
||||
if (reference.getQualifier() == null) {
|
||||
GroovySmartCompletionContributor.addExpectedClassMembers(parameters, result);
|
||||
@@ -361,6 +364,17 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
|
||||
}
|
||||
|
||||
@Nullable private static GrReferenceElement findGroovyReference(PsiElement position) {
|
||||
final PsiElement parent = position.getParent();
|
||||
if (parent instanceof GrReferenceElement) {
|
||||
return (GrReferenceElement)parent;
|
||||
}
|
||||
if (couldContainReference(position)) {
|
||||
return GroovyPsiElementFactory.getInstance(position.getProject()).createReferenceElementFromText("Foo", position);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean couldContainReference(PsiElement position) {
|
||||
return IN_CATCH_TYPE.accepts(position) ||
|
||||
AFTER_AT.accepts(position) ||
|
||||
@@ -408,31 +422,31 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
super.fillCompletionVariants(parameters, result);
|
||||
}
|
||||
|
||||
private static void completeReference(final CompletionParameters parameters,
|
||||
final CompletionResultSet result,
|
||||
GrReferenceElement reference, final InheritorsHolder inheritorsHolder) {
|
||||
static LinkedHashSet<LookupElement> completeReference(final CompletionParameters parameters,
|
||||
GrReferenceElement reference, final InheritorsHolder inheritorsHolder, final PrefixMatcher matcher) {
|
||||
final PsiElement position = parameters.getPosition();
|
||||
|
||||
if (GroovySmartCompletionContributor.AFTER_NEW.accepts(position)) {
|
||||
GroovySmartCompletionContributor.generateInheritorVariants(parameters, result.getPrefixMatcher(), inheritorsHolder);
|
||||
}
|
||||
|
||||
final int invocationCount = parameters.getInvocationCount();
|
||||
final boolean firstCompletionInvoked = invocationCount < 2;
|
||||
|
||||
final String prefix = result.getPrefixMatcher().getPrefix();
|
||||
final boolean skipAccessors = firstCompletionInvoked && !prefix.startsWith("g") && !prefix.startsWith("s") && !prefix.startsWith("i");
|
||||
result.restartCompletionOnPrefixChange("g");
|
||||
result.restartCompletionOnPrefixChange("i");
|
||||
result.restartCompletionOnPrefixChange("s");
|
||||
|
||||
final Map<PsiModifierListOwner, LookupElement> staticMembers = hashMap();
|
||||
final PsiElement qualifier = reference.getQualifier();
|
||||
final PsiType qualifierType = qualifier instanceof GrExpression ? ((GrExpression)qualifier).getType() : null;
|
||||
|
||||
LinkedHashSet<LookupElement> result = new LinkedHashSet<LookupElement>();
|
||||
if (reference instanceof GrReferenceExpression && (qualifier instanceof GrExpression || qualifier == null)) {
|
||||
for (String string : CompleteReferenceExpression.getVariantsWithSameQualifier(matcher, (GrExpression)qualifier, (GrReferenceExpression)reference)) {
|
||||
result.add(GroovyCompletionUtil.getLookupElement(string));
|
||||
}
|
||||
if (parameters.getInvocationCount() < 2 && qualifier != null && qualifierType == null) {
|
||||
if (parameters.getInvocationCount() == 1) {
|
||||
showInfo();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
final ElementFilter classFilter = getClassFilter(position);
|
||||
|
||||
reference.processVariants(result.getPrefixMatcher(), parameters, new Consumer<Object>() {
|
||||
final List<LookupElement> items = arrayList();
|
||||
reference.processVariants(matcher, parameters, new Consumer<Object>() {
|
||||
public void consume(Object element) {
|
||||
if (element instanceof PsiClass && inheritorsHolder.alreadyProcessed((PsiClass)element)) {
|
||||
return;
|
||||
@@ -445,15 +459,11 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
element = ((LookupElement)element).getObject();
|
||||
}
|
||||
|
||||
final LookupElement lookupElement = element instanceof PsiClass
|
||||
? GroovyCompletionUtil.createClassLookupItem(CompletionUtil.getOriginalOrSelf((PsiClass)element))
|
||||
: GroovyCompletionUtil.getLookupElement(element);
|
||||
LookupElement lookupElement = element instanceof PsiClass
|
||||
? GroovyCompletionUtil.createClassLookupItem(CompletionUtil.getOriginalOrSelf((PsiClass)element))
|
||||
: GroovyCompletionUtil.getLookupElement(element);
|
||||
Object object = lookupElement.getObject();
|
||||
PsiSubstitutor substitutor = null;
|
||||
GroovyResolveResult resolveResult = null;
|
||||
if (object instanceof GroovyResolveResult) {
|
||||
resolveResult = (GroovyResolveResult)object;
|
||||
substitutor = resolveResult.getSubstitutor();
|
||||
object = ((GroovyResolveResult)object).getElement();
|
||||
}
|
||||
|
||||
@@ -461,44 +471,9 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean autopopup = parameters.getInvocationCount() == 0;
|
||||
//skip default groovy methods
|
||||
if (firstCompletionInvoked &&
|
||||
object instanceof GrGdkMethod &&
|
||||
GroovyCompletionUtil.skipDefGroovyMethod((GrGdkMethod)object, substitutor, qualifierType)) {
|
||||
if (!autopopup) {
|
||||
showInfo();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//skip operator methods
|
||||
if (firstCompletionInvoked &&
|
||||
object instanceof PsiMethod &&
|
||||
GroovyCompletionUtil.OPERATOR_METHOD_NAMES.contains(((PsiMethod)object).getName())) {
|
||||
if (!checkForIterator((PsiMethod)object)) {
|
||||
if (!autopopup) {
|
||||
showInfo();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//skip accessors if there is no get, set, is prefix
|
||||
if (skipAccessors && object instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertyAccessor((PsiMethod)object)) {
|
||||
if (!autopopup) {
|
||||
showInfo();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//skip inaccessible elements
|
||||
if (firstCompletionInvoked && resolveResult != null && !resolveResult.isAccessible()) {
|
||||
if (!autopopup) {
|
||||
showInfo();
|
||||
}
|
||||
return;
|
||||
}
|
||||
int priority = assignPriority(lookupElement, qualifierType);
|
||||
lookupElement = JavaCompletionUtil.highlightIfNeeded(qualifierType,
|
||||
PrioritizedLookupElement.withPriority(lookupElement, priority), object);
|
||||
|
||||
if ((object instanceof PsiMethod || object instanceof PsiField) &&
|
||||
((PsiModifierListOwner)object).hasModifierProperty(PsiModifier.STATIC)) {
|
||||
@@ -510,7 +485,8 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
if (object instanceof PsiClass && !classFilter.isAcceptable(object, position)) {
|
||||
return;
|
||||
}
|
||||
result.addElement(JavaCompletionUtil.highlightIfNeeded(qualifierType, lookupElement, object));
|
||||
|
||||
items.add(lookupElement);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -522,7 +498,7 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
member = ((GrAccessorMethod)member).getProperty();
|
||||
}
|
||||
final String name = member.getName();
|
||||
if (name == null || !result.getPrefixMatcher().prefixMatches(name)) {
|
||||
if (name == null || !matcher.prefixMatches(name)) {
|
||||
staticMembers.remove(member);
|
||||
return;
|
||||
}
|
||||
@@ -532,7 +508,26 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
});
|
||||
|
||||
}
|
||||
result.addAllElements(staticMembers.values());
|
||||
items.addAll(staticMembers.values());
|
||||
|
||||
for (Iterator<LookupElement> iterator = items.iterator(); iterator.hasNext(); ) {
|
||||
LookupElement element = iterator.next();
|
||||
PrioritizedLookupElement prio = element.as(PrioritizedLookupElement.CLASS_CONDITION_KEY);
|
||||
if (prio == null || prio.getPriority() >= 0) {
|
||||
result.add(element);
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
result.addAll(items);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void showInfo() {
|
||||
if (StringUtil.isEmpty(CompletionService.getCompletionService().getAdvertisementText())) {
|
||||
CompletionService.getCompletionService()
|
||||
.setAdvertisementText(GroovyBundle.message("invoke.completion.second.time.to.show.skipped.methods"));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkForIterator(PsiMethod method) {
|
||||
@@ -545,11 +540,39 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
return InheritanceUtil.isInheritorOrSelf(containingClass, iterator, true);
|
||||
}
|
||||
|
||||
private static void showInfo() {
|
||||
if (StringUtil.isEmpty(CompletionService.getCompletionService().getAdvertisementText())) {
|
||||
CompletionService.getCompletionService()
|
||||
.setAdvertisementText(GroovyBundle.message("invoke.completion.second.time.to.show.skipped.methods"));
|
||||
|
||||
private static int assignPriority(LookupElement lookupElement, PsiType qualifierType) {
|
||||
Object object = lookupElement.getObject();
|
||||
PsiSubstitutor substitutor = null;
|
||||
GroovyResolveResult resolveResult = null;
|
||||
if (object instanceof GroovyResolveResult) {
|
||||
resolveResult = (GroovyResolveResult)object;
|
||||
substitutor = resolveResult.getSubstitutor();
|
||||
object = ((GroovyResolveResult)object).getElement();
|
||||
}
|
||||
|
||||
// default groovy methods
|
||||
if (object instanceof GrGdkMethod &&
|
||||
GroovyCompletionUtil.skipDefGroovyMethod((GrGdkMethod)object, substitutor, qualifierType)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// operator methods
|
||||
if (object instanceof PsiMethod &&
|
||||
GroovyCompletionUtil.OPERATOR_METHOD_NAMES.contains(((PsiMethod)object).getName()) && !checkForIterator((PsiMethod)object)) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
// accessors if there is no get, set, is prefix
|
||||
if (object instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertyAccessor((PsiMethod)object)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// inaccessible elements
|
||||
if (resolveResult != null && !resolveResult.isAccessible()) {
|
||||
return -2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static StaticMemberProcessor completeStaticMembers(CompletionParameters parameters) {
|
||||
|
||||
+119
-20
@@ -16,9 +16,21 @@
|
||||
package org.jetbrains.plugins.groovy.lang.completion;
|
||||
|
||||
import com.intellij.codeInsight.completion.*;
|
||||
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
|
||||
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -27,27 +39,114 @@ public class GroovyNoVariantsDelegator extends NoVariantsDelegator {
|
||||
|
||||
@Override
|
||||
protected void delegate(CompletionParameters parameters, CompletionResultSet result, Consumer<CompletionResult> passResult) {
|
||||
if (parameters.getCompletionType() == CompletionType.BASIC &&
|
||||
parameters.getInvocationCount() <= 1 &&
|
||||
JavaCompletionContributor.mayStartClassName(result, false) &&
|
||||
GroovyCompletionContributor.isClassNamePossible(parameters.getPosition()) &&
|
||||
!MapArgumentCompletionProvider.isMapKeyCompletion(parameters)) {
|
||||
final ClassByNameMerger merger = new ClassByNameMerger(parameters.getInvocationCount() == 0, result);
|
||||
|
||||
GroovyCompletionContributor.addAllClasses(parameters, result,
|
||||
new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement element) {
|
||||
JavaPsiClassReferenceElement classElement = element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY);
|
||||
if (classElement != null) {
|
||||
classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
|
||||
}
|
||||
merger.consume(classElement);
|
||||
}
|
||||
}, new InheritorsHolder(parameters.getPosition(), result));
|
||||
|
||||
merger.finishedClassProcessing();
|
||||
if (parameters.getCompletionType() == CompletionType.BASIC) {
|
||||
if (parameters.getInvocationCount() <= 1 &&
|
||||
JavaCompletionContributor.mayStartClassName(result, false) &&
|
||||
GroovyCompletionContributor.isClassNamePossible(parameters.getPosition()) &&
|
||||
!MapArgumentCompletionProvider.isMapKeyCompletion(parameters)) {
|
||||
suggestNonImportedClasses(parameters, result);
|
||||
}
|
||||
|
||||
suggestChainedCalls(parameters, result);
|
||||
}
|
||||
}
|
||||
|
||||
private static void suggestNonImportedClasses(CompletionParameters parameters, CompletionResultSet result) {
|
||||
final ClassByNameMerger merger = new ClassByNameMerger(parameters.getInvocationCount() == 0, result);
|
||||
|
||||
GroovyCompletionContributor.addAllClasses(parameters, new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement element) {
|
||||
JavaPsiClassReferenceElement classElement =
|
||||
element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY);
|
||||
if (classElement != null) {
|
||||
classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
|
||||
}
|
||||
merger.consume(classElement);
|
||||
}
|
||||
}, new InheritorsHolder(parameters.getPosition(), result), result.getPrefixMatcher());
|
||||
|
||||
merger.finishedClassProcessing();
|
||||
}
|
||||
|
||||
private static void suggestChainedCalls(CompletionParameters parameters, CompletionResultSet result) {
|
||||
PsiElement position = parameters.getPosition();
|
||||
PsiElement parent = position.getParent();
|
||||
if (!(parent instanceof GrReferenceElement)) {
|
||||
return;
|
||||
}
|
||||
PsiElement qualifier = ((GrReferenceElement)parent).getQualifier();
|
||||
if (!(qualifier instanceof GrReferenceElement) ||
|
||||
((GrReferenceElement)qualifier).getQualifier() != null ||
|
||||
((GrReferenceElement)qualifier).resolve() != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String fullPrefix = position.getContainingFile().getText().substring(parent.getTextRange().getStartOffset(), parameters.getOffset());
|
||||
final CompletionResultSet qualifiedCollector = result.withPrefixMatcher(fullPrefix);
|
||||
InheritorsHolder inheritors = new InheritorsHolder(position, result);
|
||||
for (final LookupElement base : suggestQualifierItems(parameters, (GrReferenceElement)qualifier, inheritors)) {
|
||||
final PsiType type = JavaCompletionUtil.getLookupElementType(base);
|
||||
if (type != null && !PsiType.VOID.equals(type)) {
|
||||
GrReferenceElement ref = createMockReference(position, type, base);
|
||||
PsiElement refName = ref.getReferenceNameElement();
|
||||
assert refName != null;
|
||||
for (LookupElement element : GroovyCompletionContributor.completeReference(
|
||||
parameters.withPosition(refName, refName.getTextRange().getStartOffset()), ref, inheritors, result.getPrefixMatcher())) {
|
||||
qualifiedCollector.addElement(new JavaChainLookupElement(base, element) {
|
||||
@Override
|
||||
protected boolean shouldParenthesizeQualifier(PsiFile file, int startOffset, int endOffset) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static GrReferenceElement createMockReference(final PsiElement place, @NotNull PsiType qualifierType, LookupElement qualifierItem) {
|
||||
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(place.getProject());
|
||||
if (qualifierItem.getObject() instanceof PsiClass) {
|
||||
return factory
|
||||
.createReferenceExpressionFromText(((PsiClass)qualifierItem.getObject()).getQualifiedName() + ".xxx", place);
|
||||
}
|
||||
|
||||
return factory.createReferenceExpressionFromText("xxx.xxx",
|
||||
ReferenceExpressionCompletionContributor
|
||||
.createContextWithXxxVariable(place, qualifierType));
|
||||
}
|
||||
|
||||
|
||||
private static Set<LookupElement> suggestQualifierItems(CompletionParameters _parameters,
|
||||
GrReferenceElement qualifier,
|
||||
InheritorsHolder inheritors) {
|
||||
CompletionParameters parameters =
|
||||
_parameters.withPosition(qualifier.getReferenceNameElement(), qualifier.getTextRange().getEndOffset());
|
||||
String referenceName = qualifier.getReferenceName();
|
||||
if (referenceName == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
final PrefixMatcher qMatcher = new CamelHumpMatcher(referenceName);
|
||||
final Set<LookupElement> variants = new LinkedHashSet<LookupElement>();
|
||||
for (LookupElement element : GroovyCompletionContributor.completeReference(parameters, qualifier, inheritors, qMatcher)) {
|
||||
if (qMatcher.prefixMatches(element)) {
|
||||
variants.add(element);
|
||||
}
|
||||
}
|
||||
|
||||
if (variants.isEmpty()) {
|
||||
GroovyCompletionContributor.addAllClasses(parameters, new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement element) {
|
||||
if (qMatcher.prefixMatches(element)) {
|
||||
variants.add(element);
|
||||
}
|
||||
}
|
||||
}, inheritors, qMatcher);
|
||||
}
|
||||
return variants;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+8
-13
@@ -25,7 +25,6 @@ import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.hash.HashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -48,7 +47,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrRe
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GrClassImplUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ClosureMissingMethodContributor;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
@@ -88,7 +86,6 @@ public class CompleteReferenceExpression {
|
||||
|
||||
private static void getVariantsImpl(PrefixMatcher matcher, GrReferenceExpression refExpr, CompleteReferenceProcessor processor) {
|
||||
GrExpression qualifier = refExpr.getQualifierExpression();
|
||||
getVariantsWithSameQualifier(matcher, qualifier, refExpr, processor);
|
||||
if (qualifier == null) {
|
||||
ResolveUtil.treeWalkUp(refExpr, processor, true);
|
||||
|
||||
@@ -228,7 +225,8 @@ public class CompleteReferenceExpression {
|
||||
return;
|
||||
}
|
||||
}
|
||||
getVariantsFromQualifierType(refExpr, processor, GrClassImplUtil.getGroovyObjectType(refExpr), project);
|
||||
getVariantsFromQualifierType(refExpr, processor,
|
||||
PsiType.getJavaLangObject(refExpr.getManager(), qualifier.getResolveScope()), project);
|
||||
}
|
||||
else if (qualifierType instanceof PsiIntersectionType) {
|
||||
for (PsiType conjunct : ((PsiIntersectionType)qualifierType).getConjuncts()) {
|
||||
@@ -256,20 +254,19 @@ public class CompleteReferenceExpression {
|
||||
}
|
||||
}
|
||||
|
||||
private static String[] getVariantsWithSameQualifier(PrefixMatcher matcher,GrExpression qualifier, GrReferenceExpression refExpr, CompleteReferenceProcessor processor) {
|
||||
if (qualifier != null && qualifier.getType() != null) return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
public static Set<String> getVariantsWithSameQualifier(PrefixMatcher matcher, @Nullable GrExpression qualifier, GrReferenceExpression refExpr) {
|
||||
if (qualifier != null && qualifier.getType() != null) return Collections.emptySet();
|
||||
|
||||
final PsiElement scope = PsiTreeUtil.getParentOfType(refExpr, GrMember.class, PsiFile.class);
|
||||
Set<String> result = new LinkedHashSet<String>();
|
||||
addVariantsWithSameQualifier(matcher, scope, refExpr, qualifier, result, processor);
|
||||
return ArrayUtil.toStringArray(result);
|
||||
addVariantsWithSameQualifier(matcher, scope, refExpr, qualifier, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void addVariantsWithSameQualifier(PrefixMatcher matcher, PsiElement element,
|
||||
GrReferenceExpression patternExpression,
|
||||
GrExpression patternQualifier,
|
||||
Set<String> result,
|
||||
CompleteReferenceProcessor processor) {
|
||||
Set<String> result) {
|
||||
if (element instanceof GrReferenceExpression && element != patternExpression && !PsiUtil.isLValue((GroovyPsiElement)element)) {
|
||||
final GrReferenceExpression refExpr = (GrReferenceExpression)element;
|
||||
final String refName = refExpr.getReferenceName();
|
||||
@@ -279,21 +276,19 @@ public class CompleteReferenceExpression {
|
||||
if (PsiEquivalenceUtil.areElementsEquivalent(hisQualifier, patternQualifier)) {
|
||||
if (refExpr.resolve() == null) {
|
||||
result.add(refName);
|
||||
processor.consume(refName);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (hisQualifier == null && patternQualifier == null) {
|
||||
if (refExpr.resolve() == null) {
|
||||
result.add(refName);
|
||||
processor.consume(refName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (PsiElement child = element.getFirstChild(); child != null; child = child.getNextSibling()) {
|
||||
addVariantsWithSameQualifier(matcher, child, patternExpression, patternQualifier, result, processor);
|
||||
addVariantsWithSameQualifier(matcher, child, patternExpression, patternQualifier, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+61
-1
@@ -170,7 +170,67 @@ toString
|
||||
wait
|
||||
wait
|
||||
wait
|
||||
with\
|
||||
with
|
||||
getThisProp
|
||||
setThisProp
|
||||
getSuperProp
|
||||
setSuperProp
|
||||
addShutdownHook
|
||||
any
|
||||
any
|
||||
asBoolean
|
||||
asType
|
||||
collect
|
||||
collect
|
||||
dump
|
||||
each
|
||||
eachWithIndex
|
||||
every
|
||||
every
|
||||
find
|
||||
findAll
|
||||
findIndexOf
|
||||
findIndexOf
|
||||
findIndexValues
|
||||
findIndexValues
|
||||
findLastIndexOf
|
||||
findLastIndexOf
|
||||
getAt
|
||||
getClass
|
||||
getMetaClass
|
||||
getMetaPropertyValues
|
||||
getProperties
|
||||
grep
|
||||
hasPerInstanceMetaClass
|
||||
hasProperty
|
||||
identity
|
||||
inject
|
||||
inspect
|
||||
is
|
||||
isCase
|
||||
iterator
|
||||
metaClass
|
||||
primitiveArrayGet
|
||||
primitiveArrayGet
|
||||
primitiveArrayGet
|
||||
primitiveArrayPut
|
||||
print
|
||||
print
|
||||
printf
|
||||
printf
|
||||
println
|
||||
println
|
||||
println
|
||||
putAt
|
||||
respondsTo
|
||||
respondsTo
|
||||
setMetaClass
|
||||
split
|
||||
sprintf
|
||||
sprintf
|
||||
use
|
||||
use
|
||||
use\
|
||||
""".split('\n')
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -56,7 +56,7 @@ class GroovyAutoPopupTest extends CompletionAutoPopupTestCase {
|
||||
public void testNoLookupFocusOnUnresolvedQualifier() {
|
||||
myFixture.configureByText("a.groovy", """xxx.<caret>""")
|
||||
type 'h' //hashCode
|
||||
assert !lookup.focused
|
||||
assert !lookup
|
||||
}
|
||||
|
||||
public void testNoLookupFocusOnUntypedQualifier() {
|
||||
@@ -65,7 +65,7 @@ class GroovyAutoPopupTest extends CompletionAutoPopupTestCase {
|
||||
xxx.<caret>
|
||||
}""")
|
||||
type 'h'
|
||||
assert !lookup.focused
|
||||
assert !lookup
|
||||
}
|
||||
|
||||
public void testPossibleClosureParameter() {
|
||||
|
||||
+21
-11
@@ -891,16 +891,6 @@ class B extends A {
|
||||
checkCompletion "asse<caret>x", ' ', 'assert <caret>x'
|
||||
}
|
||||
|
||||
public void testDontShowAccessors() {
|
||||
assertNull doContainsTest("getFoo", """
|
||||
class MyClass {
|
||||
def foo
|
||||
}
|
||||
|
||||
def a = new MyClass()
|
||||
a.<caret>""")
|
||||
}
|
||||
|
||||
public void testPreferInstanceof() {
|
||||
caseSensitiveNone()
|
||||
|
||||
@@ -1072,7 +1062,7 @@ class X {
|
||||
}
|
||||
|
||||
public void testSortOrder0() {
|
||||
doVariantableTest 'se', 'setMetaClass', 'setProperty', 'setSe'
|
||||
doVariantableTest 'se', 'setProperty', 'setMetaClass', 'setSe'
|
||||
}
|
||||
|
||||
public void testPrimitiveCastOverwrite() {
|
||||
@@ -1118,9 +1108,29 @@ public class KeyVO {
|
||||
checkSingleItemCompletion 'class Foo impl<caret> {}', 'class Foo implements <caret> {}'
|
||||
}
|
||||
|
||||
public void testAmbiguousClassQualifier() {
|
||||
myFixture.addClass("package foo; public class Util { public static void foo() {} }")
|
||||
myFixture.addClass("package bar; public class Util { public static void bar() {} }")
|
||||
myFixture.configureByText 'a.groovy', 'Util.<caret>'
|
||||
myFixture.completeBasic()
|
||||
assert myFixture.lookupElementStrings[0..1] == ['Util.bar', 'Util.foo']
|
||||
|
||||
def presentation = LookupElementPresentation.renderElement(myFixture.lookupElements[0])
|
||||
assert 'Util.bar' == presentation.itemText
|
||||
assert '() (bar)' == presentation.tailText
|
||||
assert !presentation.tailGrayed
|
||||
|
||||
myFixture.type 'f\n'
|
||||
myFixture.checkResult '''import foo.Util
|
||||
|
||||
Util.foo()<caret>'''
|
||||
}
|
||||
|
||||
public void testPreferInterfacesInImplements() {
|
||||
myFixture.addClass('interface FooIntf {}')
|
||||
myFixture.addClass('class FooClass {}')
|
||||
doVariantableTest('FooIntf', 'FooClass')
|
||||
}
|
||||
|
||||
public void testPropertyChain() { doBasicTest() }
|
||||
}
|
||||
+1
-1
@@ -50,7 +50,7 @@ class GroovyTransformationsTest extends LightCodeInsightFixtureTestCase {
|
||||
|
||||
public void testVetoableTransform() throws Throwable { doPlainTest() }
|
||||
|
||||
public void testNewifyTransform1() throws Throwable { doVariantsTest('newInstance', 'new', 'new', 'newInstance') }
|
||||
public void testNewifyTransform1() throws Throwable { doVariantsTest('newInstance', 'new', 'new', 'newInstance', 'negative', 'next') }
|
||||
|
||||
public void testNewifyTransform2() throws Throwable { doVariantsTest('Leaf', 'Leaf', 'Leaf') }
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
class A {
|
||||
File myFile;
|
||||
|
||||
def foo() {
|
||||
myf.cap<caret>
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class A {
|
||||
File myFile;
|
||||
|
||||
def foo() {
|
||||
myFile.canonicalPath<caret>
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
def (street, home, postCode)
|
||||
def s = street.toS<caret>
|
||||
-----
|
||||
toString
|
||||
-----
|
||||
@@ -1,3 +1,2 @@
|
||||
unknown.metaCl<caret>
|
||||
-----
|
||||
metaClass
|
||||
-----
|
||||
+28
-12
@@ -61,6 +61,7 @@ public class XsltVariableContext implements VariableContext<XsltVariable> {
|
||||
final VariantsProcessor processor = new VariantsProcessor(context);
|
||||
|
||||
ResolveUtil.treeWalkUp(processor, context);
|
||||
processForwardGlobals(context, processor);
|
||||
return processor.getResult();
|
||||
}
|
||||
|
||||
@@ -75,19 +76,32 @@ public class XsltVariableContext implements VariableContext<XsltVariable> {
|
||||
final ResolveProcessor processor = new ResolveProcessor(reference.getReferencedName(), context);
|
||||
|
||||
final XPathVariable variable = (XPathVariable)ResolveUtil.treeWalkUp(processor, context);
|
||||
if (variable == null) {
|
||||
final XmlFile file = PsiTreeUtil.getParentOfType(context, XmlFile.class, true);
|
||||
if (file != null) {
|
||||
XsltIncludeIndex.processBackwardDependencies(file, new Processor<XmlFile>() {
|
||||
public boolean process(XmlFile xmlFile) {
|
||||
processor.processExternalFile(xmlFile, context);
|
||||
return processor.shouldContinue();
|
||||
}
|
||||
});
|
||||
return (XPathVariable)processor.getResult();
|
||||
}
|
||||
if (variable != null) {
|
||||
return variable;
|
||||
}
|
||||
return variable;
|
||||
if (!processForwardGlobals(context, processor)) {
|
||||
final XmlFile file = PsiTreeUtil.getParentOfType(context, XmlFile.class, true);
|
||||
if (file != null) {
|
||||
XsltIncludeIndex.processBackwardDependencies(file, new Processor<XmlFile>() {
|
||||
public boolean process(XmlFile xmlFile) {
|
||||
processor.processExternalFile(xmlFile, context);
|
||||
return processor.shouldContinue();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return (XPathVariable)processor.getResult();
|
||||
}
|
||||
|
||||
private static boolean processForwardGlobals(XmlTag context, VariableProcessor processor) {
|
||||
while (context != null && !XsltSupport.isTopLevelElement(context)) {
|
||||
context = context.getParentTag();
|
||||
}
|
||||
while (context != null && processor.shouldContinue()) {
|
||||
processor.process(context);
|
||||
context = PsiTreeUtil.getNextSiblingOfType(context, XmlTag.class);
|
||||
}
|
||||
return !processor.shouldContinue();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -141,6 +155,8 @@ public class XsltVariableContext implements VariableContext<XsltVariable> {
|
||||
processVarOrParamImpl(tag);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract boolean shouldContinue();
|
||||
}
|
||||
|
||||
static class VariantsProcessor extends VariableProcessor {
|
||||
|
||||
@@ -40,6 +40,10 @@ public class XsltResolveTest extends TestBase {
|
||||
doVariableResolveTest(true);
|
||||
}
|
||||
|
||||
public void testResolveForwardVariable() throws Throwable {
|
||||
doVariableResolveTest(true);
|
||||
}
|
||||
|
||||
public void testResolveSingleVariable() throws Throwable {
|
||||
doVariableResolveTest(false);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<xsl:variable name="a" select="$<caret>b + 1"/>
|
||||
|
||||
<xsl:variable name="b" select="2"/>
|
||||
</xsl:stylesheet>
|
||||
@@ -213,10 +213,12 @@
|
||||
<completion.confidence language="JAVA" implementationClass="com.intellij.codeInsight.completion.AlwaysFocusLookup" id="javaTrue" order="last"/>
|
||||
<completion.confidence language="JAVA" implementationClass="com.intellij.codeInsight.completion.SkipAutopopupInStrings" id="javaSkipAutopopupInStrings"/>
|
||||
|
||||
<completion.contributor language="JAVA" implementationClass="com.intellij.codeInspection.magicConstant.MagicCompletionContributor"
|
||||
id="magicCompletion, after javaBasic2ClassName"/>
|
||||
<completion.contributor language="JAVA" implementationClass="com.intellij.codeInsight.completion.JavaNoVariantsDelegator" id="javaBasic2ClassName"
|
||||
order="first, before javaMemberName, after liveTemplates"/>
|
||||
order="before javaMemberName, before javaLegacy, after liveTemplates"/>
|
||||
<completion.contributor language="XML" implementationClass="com.intellij.codeInsight.completion.XmlBasicToClassNameDelegator" id="basic2ClassName"
|
||||
order="first, after xml"/>
|
||||
order="after xml"/>
|
||||
<completion.contributor language="JAVA" implementationClass="com.intellij.codeInsight.completion.JavaCompletionContributor" id="javaLegacy"
|
||||
order="last, before legacy, before default, before javaClassName"/>
|
||||
<completion.contributor language="any" implementationClass="com.intellij.codeInsight.completion.JavaClassReferenceCompletionContributor"
|
||||
@@ -1212,6 +1214,8 @@
|
||||
<wizardMode implementation="com.intellij.ide.util.newProjectWizard.modes.CreateModuleFromSourcesMode" id="CreateModuleFromSourcesMode" order="after CreateProjectFromSourcesMode"/>
|
||||
<projectStructureDetector implementation="com.intellij.ide.util.projectWizard.importSources.impl.JavaProjectStructureDetector" order="first"/>
|
||||
|
||||
<applicationService serviceImplementation="com.intellij.execution.JavaRunConfigurationExtensionManager"/>
|
||||
|
||||
<regExpLanguageHost forClass="com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl"
|
||||
implementationClass="com.intellij.psi.impl.JavaRegExpHost"/>
|
||||
</extensions>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -66,7 +66,7 @@ public class BrowsersConfiguration implements PersistentStateComponent<Element>
|
||||
return new FirefoxSettings();
|
||||
}
|
||||
},
|
||||
CHROME(XmlBundle.message("browsers.chrome"), getWindowsPathToChrome(), "google-chrome", null, IconLoader.getIcon("/xml/browsers/chrome16.png")) {
|
||||
CHROME(XmlBundle.message("browsers.chrome"), getWindowsPathToChrome(), "google-chrome", "Google Chrome", IconLoader.getIcon("/xml/browsers/chrome16.png")) {
|
||||
@Override
|
||||
public BrowserSpecificSettings createBrowserSpecificSettings() {
|
||||
return new ChromeSettings();
|
||||
|
||||
Reference in New Issue
Block a user