Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2015-04-21 14:11:03 +02:00
33 changed files with 383 additions and 121 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -34,7 +34,7 @@ import org.jetbrains.annotations.Nullable;
public class RefImplicitConstructorImpl extends RefMethodImpl implements RefImplicitConstructor {
RefImplicitConstructorImpl(RefClass ownerClass) {
RefImplicitConstructorImpl(@NotNull RefClass ownerClass) {
super(InspectionsBundle.message("inspection.reference.implicit.constructor.name", ownerClass.getName()), ownerClass);
}
@@ -47,7 +47,7 @@ public abstract class RefJavaElementImpl extends RefElementImpl implements RefJa
private static final int IS_USES_DEPRECATION_MASK = 0x200;
private static final int IS_SYNTHETIC_JSP_ELEMENT_MASK = 0x400;
protected RefJavaElementImpl(String name, @NotNull RefJavaElement owner) {
protected RefJavaElementImpl(@NotNull String name, @NotNull RefJavaElement owner) {
super(name, owner);
String am = owner.getAccessModifier();
doSetAccessModifier(am);
@@ -91,6 +91,7 @@ public abstract class RefJavaElementImpl extends RefElementImpl implements RefJa
myOutTypeReferences.add(refClass);
}
@NotNull
public static String getName(PsiElement element) {
if (element instanceof PsiAnonymousClass) {
PsiAnonymousClass psiAnonymousClass = (PsiAnonymousClass)element;
@@ -67,7 +67,7 @@ public class RefMethodImpl extends RefJavaElementImpl implements RefMethod {
}
// To be used only from RefImplicitConstructor.
protected RefMethodImpl(String name, @NotNull RefClass ownerClass) {
protected RefMethodImpl(@NotNull String name, @NotNull RefClass ownerClass) {
super(name, ownerClass);
myOwnerClass = ownerClass;
((RefClassImpl)ownerClass).add(this);
@@ -79,7 +79,7 @@ public class RefMethodImpl extends RefJavaElementImpl implements RefMethod {
}
@Override
public void add(RefEntity child) {
public void add(@NotNull RefEntity child) {
if (child instanceof RefParameter) {
return;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -45,6 +45,7 @@ public class RefPackageImpl extends RefEntityImpl implements RefPackage {
return myQualifiedName;
}
@NotNull
private static String getPackageSuffix(@NotNull String fullName) {
int dotIndex = fullName.lastIndexOf('.');
return (dotIndex >= 0) ? fullName.substring(dotIndex + 1) : fullName;
@@ -43,6 +43,7 @@ public interface QuickFix<D extends CommonProblemDescriptor> {
* if the name of the quickfix is "Create template &lt;filename&gt", the return value of getFamilyName() should be "Create template".
* If the name of the quickfix does not depend on a specific element, simply return getName().
*/
@Nls(capitalization = Nls.Capitalization.Sentence)
@NotNull
String getFamilyName();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -64,7 +64,7 @@ public abstract class RefElementImpl extends RefEntityImpl implements RefElement
private final Module myModule;
protected static final int IS_REACHABLE_MASK = 0x40;
protected RefElementImpl(String name, @NotNull RefElement owner) {
protected RefElementImpl(@NotNull String name, @NotNull RefElement owner) {
super(name, owner.getRefManager());
myID = null;
myFlags = 0;
@@ -75,7 +75,7 @@ public abstract class RefElementImpl extends RefEntityImpl implements RefElement
this(file.getName(), file, manager);
}
protected RefElementImpl(String name, @NotNull PsiElement element, @NotNull RefManager manager) {
protected RefElementImpl(@NotNull String name, @NotNull PsiElement element, @NotNull RefManager manager) {
super(name, manager);
myID = SmartPointerManager.getInstance(manager.getProject()).createSmartPsiElementPointer(element);
myFlags = 0;
@@ -24,8 +24,8 @@
*/
package com.intellij.codeInspection.reference;
import com.intellij.codeInspection.InspectionsBundle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Key;
import com.intellij.util.BitUtil;
import gnu.trove.THashMap;
@@ -36,18 +36,17 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public abstract class RefEntityImpl implements RefEntity {
private static final String NO_NAME = InspectionsBundle.message("inspection.reference.noname");
private RefEntityImpl myOwner;
protected List<RefEntity> myChildren;
abstract class RefEntityImpl implements RefEntity {
private RefEntityImpl myOwner; // guarded by myManager.myLock
protected List<RefEntity> myChildren; // guarded by myManager.myLock
private final String myName;
private Map<Key, Object> myUserMap;
protected long myFlags;
protected final RefManagerImpl myManager;
protected RefEntityImpl(String name, @NotNull RefManager manager) {
RefEntityImpl(@NotNull String name, @NotNull RefManager manager) {
myManager = (RefManagerImpl)manager;
myName = name != null ? name : NO_NAME;
myName = name;
myOwner = null;
myChildren = null;
}
@@ -66,32 +65,57 @@ public abstract class RefEntityImpl implements RefEntity {
@Override
public List<RefEntity> getChildren() {
return myChildren;
return myManager.doRead(new Computable<List<RefEntity>>() {
@Override
public List<RefEntity> compute() {
return myChildren;
}
});
}
@Override
public RefEntity getOwner() {
return myOwner;
return myManager.doRead(new Computable<RefEntity>() {
@Override
public RefEntity compute() {
return myOwner;
}
});
}
protected void setOwner(RefEntityImpl owner) {
myOwner = owner;
protected void setOwner(final RefEntityImpl owner) {
myManager.doWrite(new Runnable() {
@Override
public void run() {
myOwner = owner;
}
});
}
public void add(RefEntity child) {
if (myChildren == null) {
myChildren = new ArrayList<RefEntity>(1);
}
public void add(@NotNull final RefEntity child) {
myManager.doWrite(new Runnable() {
@Override
public void run() {
if (myChildren == null) {
myChildren = new ArrayList<RefEntity>(1);
}
myChildren.add(child);
((RefEntityImpl)child).setOwner(this);
myChildren.add(child);
((RefEntityImpl)child).setOwner(RefEntityImpl.this);
}
});
}
protected void removeChild(RefEntity child) {
if (myChildren != null) {
myChildren.remove(child);
((RefEntityImpl)child).setOwner(null);
}
protected void removeChild(@NotNull final RefEntity child) {
myManager.doWrite(new Runnable() {
@Override
public void run() {
if (myChildren != null) {
myChildren.remove(child);
((RefEntityImpl)child).setOwner(null);
}
}
});
}
public String toString() {
@@ -59,6 +59,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class RefManagerImpl extends RefManager {
@@ -85,7 +86,7 @@ public class RefManagerImpl extends RefManager {
private final Map<Key, RefManagerExtension> myExtensions = new HashMap<Key, RefManagerExtension>();
private final Map<Language, RefManagerExtension> myLanguageExtensions = new HashMap<Language, RefManagerExtension>();
private final ReentrantReadWriteLock myLock = new ReentrantReadWriteLock();
private final ReadWriteLock myLock = new ReentrantReadWriteLock();
public RefManagerImpl(@NotNull Project project, @Nullable AnalysisScope scope, @NotNull GlobalInspectionContext context) {
myProject = project;
@@ -533,9 +534,9 @@ public class RefManagerImpl extends RefManager {
protected <T extends RefElement> T getFromRefTableOrCache(final PsiElement element,
@NotNull NullableFactory<T> factory,
@Nullable Consumer<T> whenCached) {
T result;
myLock.readLock().lock();
T result;
try {
//noinspection unchecked
result = (T)myRefTable.get(ApplicationManager.getApplication().runReadAction(
@@ -624,6 +625,26 @@ public class RefManagerImpl extends RefManager {
}
}
public void doWrite(@NotNull Runnable runnable) {
myLock.writeLock().lock();
try {
runnable.run();
}
finally {
myLock.writeLock().unlock();
}
}
public <T> T doRead(@NotNull Computable<T> runnable) {
myLock.readLock().lock();
try {
return runnable.compute();
}
finally {
myLock.readLock().unlock();
}
}
@Override
public boolean belongsToScope(final PsiElement psiElement) {
return belongsToScope(psiElement, false);
@@ -1,3 +1,18 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInspection.reference;
import com.intellij.openapi.application.ApplicationManager;
@@ -14,32 +29,42 @@ import java.util.ArrayList;
* User: anna
* Date: 09-Jan-2006
*/
public class RefModuleImpl extends RefEntityImpl implements RefModule {
class RefModuleImpl extends RefEntityImpl implements RefModule {
private final Module myModule;
protected RefModuleImpl(@NotNull Module module, @NotNull RefManager manager) {
RefModuleImpl(@NotNull Module module, @NotNull RefManager manager) {
super(module.getName(), manager);
myModule = module;
((RefProjectImpl)manager.getRefProject()).add(this);
}
@Override
public void add(RefEntity child) {
if (myChildren == null) {
myChildren = new ArrayList<RefEntity>();
}
myChildren.add(child);
public void add(@NotNull final RefEntity child) {
myManager.doWrite(new Runnable() {
@Override
public void run() {
if (myChildren == null) {
myChildren = new ArrayList<RefEntity>();
}
myChildren.add(child);
if (child.getOwner() == null) {
((RefEntityImpl)child).setOwner(this);
}
if (child.getOwner() == null) {
((RefEntityImpl)child).setOwner(RefModuleImpl.this);
}
}
});
}
@Override
protected void removeChild(RefEntity child) {
if (myChildren != null) {
myChildren.remove(child);
}
protected void removeChild(@NotNull final RefEntity child) {
myManager.doWrite(new Runnable() {
@Override
public void run() {
if (myChildren != null) {
myChildren.remove(child);
}
}
});
}
@Override
@@ -69,7 +94,7 @@ public class RefModuleImpl extends RefEntityImpl implements RefModule {
}
@Nullable
public static RefEntity moduleFromName(final RefManager manager, final String name) {
static RefEntity moduleFromName(final RefManager manager, final String name) {
return manager.getRefModule(ModuleManager.getInstance(manager.getProject()).findModuleByName(name));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -78,7 +78,7 @@ public class FinallyFuture<V> implements AsyncFuture<V> {
}
@Override
public void onFailure(Throwable t) {
public void onFailure(@NotNull Throwable t) {
try {
myFinallyBlock.execute();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -46,8 +46,8 @@ import java.util.Collection;
import java.util.TreeSet;
public class CodeInspectionAction extends BaseAnalysisAction {
private GlobalInspectionContextImpl myGlobalInspectionContext = null;
protected InspectionProfile myExternalProfile = null;
private GlobalInspectionContextImpl myGlobalInspectionContext;
protected InspectionProfile myExternalProfile;
public CodeInspectionAction() {
super(InspectionsBundle.message("inspection.action.title"), InspectionsBundle.message("inspection.action.noun"));
@@ -1167,7 +1167,7 @@ action.ChangesView.RemoveChangeList.text=Delete Changelist
action.ChangesView.RemoveChangeList.description=Remove changelist and move all changes to default
action.ChangesView.SetDefault.text=Set Active Changelist
action.ChangesView.SetDefault.description=Set changelist to which new changes are placed by default
action.ChangesView.Move.text=Move to Another Changelist
action.ChangesView.Move.text=Move to Another Changelist...
action.ChangesView.Move.description=Move selected changes to another changelist
action.ChangesView.Diff.text=Show Diff
action.ChangesView.Diff.description=Show diff for selected change
@@ -130,6 +130,7 @@
<completion.contributor language="any" implementationClass="com.intellij.codeInsight.completion.XmlNonFirstCompletionContributor" id="xmlNonFirst" order="after xml"/>
<completion.contributor language="XML" implementationClass="com.intellij.codeInsight.completion.XmlNoVariantsDelegator" order="before xmlNonFirst"/>
<completion.contributor language="XML" implementationClass="com.intellij.codeInsight.completion.XmlLocationCompletionContributor"/>
<completion.confidence language="XML" implementationClass="com.intellij.codeInsight.completion.XmlNameCompletionConfidence" id="xml"/>
<completion.confidence language="HTML" implementationClass="com.intellij.codeInsight.completion.XmlNameCompletionConfidence" id="html"/>
@@ -263,6 +263,7 @@ public class DiffTree<OT, NT> {
if (c11 == CompareResult.DRILL_DOWN_NEEDED) {
CharSequence oldText = myOldTree.toString(oldChild);
CharSequence newText = myNewTree.toString(newChild);
// drill down only if node texts match, but when they do, match all the way down unconditionally
c11 = StringUtil.equals(oldText, newText)
? build(oldChild, newChild, level + 1, DiffTree.<OT, NT>emptyConsumer())
: CompareResult.NOT_EQUAL;
@@ -841,11 +841,16 @@ public final class AntBuildMessageView extends JPanel implements DataProvider, O
}
});
//noinspection SSBasedInspection
DumbService.getInstance(myProject).runWhenSmart(new Runnable() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (!myIsOutputPaused) {
new OutputFlusher().doFlush();
}
DumbService.getInstance(myProject).runWhenSmart(new Runnable() {
@Override
public void run() {
if (!myIsOutputPaused) {
new OutputFlusher().doFlush();
}
}
});
}
});
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
* Copyright 2000-2015 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.tasks;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.AbstractVcs;
@@ -136,8 +137,12 @@ public abstract class TaskManager {
public abstract void removeTask(LocalTask task);
@Deprecated // use {@code com.intellij.tasks.TaskManager.addTaskListener(com.intellij.tasks.TaskListener, com.intellij.openapi.Disposable)}
public abstract void addTaskListener(TaskListener listener);
public abstract void addTaskListener(@NotNull TaskListener listener, @NotNull Disposable parentDisposable);
@Deprecated // use {@code com.intellij.tasks.TaskManager.addTaskListener(com.intellij.tasks.TaskListener, com.intellij.openapi.Disposable)}
public abstract void removeTaskListener(TaskListener listener);
// repositories management
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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,7 @@
package com.intellij.tasks.impl;
import com.intellij.notification.*;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.*;
import com.intellij.openapi.diagnostic.Logger;
@@ -224,6 +225,11 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
myDispatcher.addListener(listener);
}
@Override
public void addTaskListener(@NotNull TaskListener listener, @NotNull Disposable parentDisposable) {
myDispatcher.addListener(listener, parentDisposable);
}
@Override
public void removeTaskListener(TaskListener listener) {
myDispatcher.removeListener(listener);
@@ -1,3 +1,18 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.tasks;
import com.intellij.notification.Notification;
@@ -6,6 +21,7 @@ import com.intellij.notification.NotificationsAdapter;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.util.Ref;
import com.intellij.tasks.impl.LocalTaskImpl;
import com.intellij.tasks.impl.TaskManagerImpl;
import com.intellij.tasks.impl.TaskProjectConfiguration;
import com.intellij.tasks.youtrack.YouTrackRepository;
import com.intellij.tasks.youtrack.YouTrackRepositoryType;
@@ -21,19 +37,6 @@ import java.util.List;
* @author Dmitry Avdeev
*/
public class TaskManagerTest extends TaskManagerTestCase {
public void testAddRemoveListener() throws Exception {
TaskListener listener = new TaskListenerAdapter() {
@Override
public void taskActivated(LocalTask task) {
}
};
myTaskManager.addTaskListener(listener);
myTaskManager.removeTaskListener(listener);
}
public void testTaskSwitch() throws Exception {
final Ref<Integer> count = Ref.create(0);
@@ -43,7 +46,7 @@ public class TaskManagerTest extends TaskManagerTestCase {
count.set(count.get() + 1);
}
};
myTaskManager.addTaskListener(listener);
myTaskManager.addTaskListener(listener, myTestRootDisposable);
LocalTask localTask = myTaskManager.createLocalTask("foo");
myTaskManager.activateTask(localTask, false);
assertEquals(1, count.get().intValue());
@@ -51,8 +54,6 @@ public class TaskManagerTest extends TaskManagerTestCase {
LocalTask other = myTaskManager.createLocalTask("bar");
myTaskManager.activateTask(other, false);
assertEquals(2, count.get().intValue());
myTaskManager.removeTaskListener(listener);
}
public void testNotifications() throws Exception {
@@ -71,7 +72,7 @@ public class TaskManagerTest extends TaskManagerTestCase {
throw new Exception();
}
};
myTaskManager.setRepositories(Collections.singletonList(repository));
((TaskManagerImpl)myTaskManager).setRepositories(Collections.singletonList(repository));
myTaskManager.updateIssues(null);
@@ -85,7 +86,7 @@ public class TaskManagerTest extends TaskManagerTestCase {
public void testSharedServers() throws Exception {
TaskRepository repository = new YouTrackRepository(new YouTrackRepositoryType());
repository.setShared(true);
myTaskManager.setRepositories(Collections.singletonList(repository));
((TaskManagerImpl)myTaskManager).setRepositories(Collections.singletonList(repository));
TaskProjectConfiguration configuration = ServiceManager.getService(getProject(), TaskProjectConfiguration.class);
TaskProjectConfiguration state = configuration.getState();
@@ -94,12 +95,12 @@ public class TaskManagerTest extends TaskManagerTestCase {
Element element = XmlSerializer.serialize(state);
configuration.servers.clear();
myTaskManager.setRepositories(Collections.<TaskRepository>emptyList());
((TaskManagerImpl)myTaskManager).setRepositories(Collections.<TaskRepository>emptyList());
configuration.loadState(XmlSerializer.deserialize(element, TaskProjectConfiguration.class));
assertEquals(1, state.servers.size());
myTaskManager.projectOpened();
((TaskManagerImpl)myTaskManager).projectOpened();
TaskRepository[] repositories = myTaskManager.getAllRepositories();
assertEquals(1, repositories.length);
@@ -114,7 +115,7 @@ public class TaskManagerTest extends TaskManagerTestCase {
return super.getIssues(query, max, since);
}
};
myTaskManager.setRepositories(Collections.singletonList(repository));
((TaskManagerImpl)myTaskManager).setRepositories(Collections.singletonList(repository));
List<Task> issues = myTaskManager.getIssues("");
assertEquals(1, issues.size());
@@ -126,7 +127,7 @@ public class TaskManagerTest extends TaskManagerTestCase {
public void testTaskHistoryLength() throws Exception {
TestRepository repository = new TestRepository();
int historyLength = myTaskManager.getState().taskHistoryLength;
int historyLength = ((TaskManagerImpl)myTaskManager).getState().taskHistoryLength;
for (int i = 0; i < historyLength + 100; i++) {
myTaskManager.addTask(new TaskTestUtil.TaskBuilder(Integer.toString(i), "", repository));
}
@@ -136,16 +137,17 @@ public class TaskManagerTest extends TaskManagerTestCase {
public void testBranchNameSuggestion() throws Exception {
TaskTestUtil.TaskBuilder task = new TaskTestUtil.TaskBuilder("IDEA-666", "Bad news", null);
assertEquals("IDEA-666", myTaskManager.suggestBranchName(task));
String format = myTaskManager.getState().branchNameFormat;
TaskManagerImpl taskManager = (TaskManagerImpl)myTaskManager;
assertEquals("IDEA-666", taskManager.suggestBranchName(task));
String format = taskManager.getState().branchNameFormat;
try {
myTaskManager.getState().branchNameFormat = "feature/{id}";
assertEquals("feature/IDEA-666", myTaskManager.suggestBranchName(task));
myTaskManager.getState().branchNameFormat = "{id}_{summary}";
assertEquals("IDEA-666_Bad-news", myTaskManager.suggestBranchName(task));
taskManager.getState().branchNameFormat = "feature/{id}";
assertEquals("feature/IDEA-666", taskManager.suggestBranchName(task));
taskManager.getState().branchNameFormat = "{id}_{summary}";
assertEquals("IDEA-666_Bad-news", taskManager.suggestBranchName(task));
}
finally {
myTaskManager.getState().branchNameFormat = format;
taskManager.getState().branchNameFormat = format;
}
}
}
@@ -1,3 +1,18 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.tasks;
import com.intellij.tasks.impl.TaskManagerImpl;
@@ -16,19 +31,19 @@ public abstract class TaskManagerTestCase extends LightCodeInsightFixtureTestCas
IdeaTestCase.initPlatformPrefix();
}
protected TaskManagerImpl myTaskManager;
protected TaskManager myTaskManager;
@Override
protected void setUp() throws Exception {
super.setUp();
myTaskManager = (TaskManagerImpl)TaskManager.getManager(getProject());
myTaskManager = TaskManager.getManager(getProject());
removeAllTasks();
}
@Override
protected void tearDown() throws Exception {
try {
myTaskManager.setRepositories(Collections.<TaskRepository>emptyList());
((TaskManagerImpl)myTaskManager).setRepositories(Collections.<TaskRepository>emptyList());
removeAllTasks();
}
finally {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -36,15 +36,15 @@ public class TaskSettingsTest extends TaskManagerTestCase {
TaskRepository repository = new YouTrackRepository();
String format = "foo \n bar";
repository.setCommitMessageFormat(format);
myTaskManager.setRepositories(Collections.singletonList(repository));
TaskManagerImpl.Config config = myTaskManager.getState();
((TaskManagerImpl)myTaskManager).setRepositories(Collections.singletonList(repository));
TaskManagerImpl.Config config = ((TaskManagerImpl)myTaskManager).getState();
Element element = XmlSerializer.serialize(config);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
JDOMUtil.writeDocument(new Document(element), stream, "\n");
Element element1 = JDOMUtil.load(new ByteArrayInputStream(stream.toByteArray()));
TaskManagerImpl.Config deserialize = XmlSerializer.deserialize(element1, TaskManagerImpl.Config.class);
myTaskManager.loadState(deserialize);
((TaskManagerImpl)myTaskManager).loadState(deserialize);
TaskRepository[] repositories = myTaskManager.getAllRepositories();
assertEquals(format, repositories[0].getCommitMessageFormat());
@@ -189,10 +189,7 @@ public class XmlCompletionContributor extends CompletionContributor {
if (isXmlNameCompletion(parameters) && parameters.getCompletionType() == CompletionType.BASIC) {
if (FeatureUsageTracker.getInstance().isToBeAdvertisedInLookup(TAG_NAME_COMPLETION_FEATURE, parameters.getPosition().getProject())) {
final String shortcut = getActionShortcut(IdeActions.ACTION_CODE_COMPLETION);
if (shortcut != null) {
return XmlBundle.message("tag.name.completion.hint", shortcut);
}
return XmlBundle.message("tag.name.completion.hint", shortcut);
}
}
return super.advertise(parameters);
@@ -0,0 +1,49 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.javaee.ExternalResourceManagerEx;
import com.intellij.psi.PsiReference;
import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.DependentNSReference;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
/**
* @author Dmitry Avdeev
*/
public class XmlLocationCompletionContributor extends CompletionContributor {
@Override
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiReference reference = parameters.getPosition().getContainingFile().findReferenceAt(parameters.getOffset());
if (reference instanceof PsiMultiReference) reference = ((PsiMultiReference)reference).getReferences()[0];
if (reference instanceof DependentNSReference) {
MultiMap<String, String> map = ExternalResourceManagerEx.getInstanceEx().getUrlsByNamespace(parameters.getOriginalFile().getProject());
String namespace = ((DependentNSReference)reference).getNamespaceReference().getCanonicalText();
Collection<String> strings = map.get(namespace);
for (String string : strings) {
if (!namespace.equals(string)) { // exclude namespaces from location urls
result.consume(PrioritizedLookupElement.withPriority(LookupElementBuilder.create(string), 100));
}
}
if (!strings.isEmpty()) result.stopHere();
}
}
}
@@ -712,5 +712,12 @@ public class XmlCompletionTest extends LightCodeInsightFixtureTestCase {
"xml:lang",
"xml:space");
}
public void testSchemaLocation() throws Exception {
myFixture.configureByFiles("spring-beans.xsd");
myFixture.testCompletionVariants("SchemaLocation.xml", "http://www.springframework.org/schema/beans ",
"http://www.w3.org/2001/XMLSchema ", "http://www.w3.org/2001/XMLSchema-instance ");
myFixture.testCompletionVariants("SchemaLocation2.xml", "http://www.w3.org/2001/XMLSchema.xsd");
}
}
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xsi:schemaLocation="<caret>">
</beans>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xsi:schemaLocation="http://www.w3.org/2001/XMLSchema <caret>">
</beans>
@@ -20,7 +20,7 @@ import org.jetbrains.annotations.NonNls;
/**
* @author Dmitry Avdeev
* @see com.intellij.javaee.StandardResourceProvider
* @see StandardResourceProvider
*/
public interface ResourceRegistrar {
@@ -136,7 +136,7 @@ public class MicrodataUtil {
return PsiReference.EMPTY_ARRAY;
}
String text = element.getText();
String urls = StringUtil.stripQuotesAroundValue(text);
String urls = StringUtil.unquoteString(text);
StringTokenizer tokenizer = new StringTokenizer(urls);
List<PsiReference> result = new ArrayList<PsiReference>();
while (tokenizer.hasMoreTokens()) {
@@ -153,7 +153,7 @@ public class MicrodataUtil {
@Nullable
public static String getStripedAttributeValue(@Nullable XmlTag tag, @Nls String attributeName) {
String value = tag != null ? tag.getAttributeValue(attributeName) : null;
return value != null ? StringUtil.stripQuotesAroundValue(value) : null;
return value != null ? StringUtil.unquoteString(value) : null;
}
private static class CollectNamesVisitor extends XmlRecursiveElementVisitor {
@@ -19,6 +19,7 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -133,6 +134,11 @@ public class CoreExternalResourceManager extends ExternalResourceManagerEx {
return 0;
}
@Override
public MultiMap<String, String> getUrlsByNamespace(Project project) {
throw new UnsupportedOperationException();
}
@Override
public void addResource(@NotNull @NonNls String url, @NonNls String location) {
throw new UnsupportedOperationException();
@@ -17,6 +17,7 @@ package com.intellij.javaee;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -72,4 +73,6 @@ public abstract class ExternalResourceManagerEx extends ExternalResourceManager
public abstract void setCatalogPropertiesFile(@Nullable String filePath);
public abstract long getModificationCount(@NotNull Project project);
public abstract MultiMap<String, String> getUrlsByNamespace(Project project);
}
@@ -26,13 +26,18 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.xml.XmlFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.xml.Html5SchemaProvider;
import com.intellij.xml.XmlSchemaProvider;
import com.intellij.xml.index.XmlNamespaceIndex;
import com.intellij.xml.util.XmlUtil;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
@@ -73,6 +78,31 @@ public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx imp
}
};
private final CachedValueProvider<MultiMap<String, String>> myUrlByNamespaceProvider = new CachedValueProvider<MultiMap<String, String>>() {
@Nullable
@Override
public CachedValueProvider.Result<MultiMap<String, String>> compute() {
MultiMap<String, String> result = new MultiMap<String, String>();
Collection<Map<String, Resource>> values = myStandardResources.getValue().values();
for (Map<String, Resource> map : values) {
for (Map.Entry<String, Resource> entry : map.entrySet()) {
String url = entry.getValue().getResourceUrl();
if (url != null) {
VirtualFile file = VfsUtilCore.findRelativeFile(url, null);
if (file != null) {
String namespace = XmlNamespaceIndex.computeNamespace(file);
if (namespace != null) {
result.putValue(namespace, entry.getKey());
}
}
}
}
}
return CachedValueProvider.Result.create(result, ExternalResourceManagerExImpl.this);
}
};
private String myDefaultHtmlDoctype = HTML5_DOCTYPE_ELEMENT;
private String myCatalogPropertiesFile;
@@ -535,6 +565,11 @@ public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx imp
incModificationCount();
}
@Override
public MultiMap<String, String> getUrlsByNamespace(Project project) {
return CachedValuesManager.getManager(project).getCachedValue(project, myUrlByNamespaceProvider);
}
@Nullable
private XMLCatalogManager getCatalogManager() {
if (myCatalogManager == null && myCatalogPropertiesFile != null) {
@@ -20,20 +20,22 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.ArrayUtil;
import com.intellij.xml.util.XmlUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class DependentNSReference extends BasicAttributeValueReference {
@NotNull
private final URLReference myReference;
private final boolean myForceFetchResultValid;
public DependentNSReference(final PsiElement element, TextRange range, URLReference ref) {
public DependentNSReference(final PsiElement element, TextRange range, @NotNull URLReference ref) {
this(element, range, ref, false);
}
public DependentNSReference(final PsiElement element,
TextRange range,
URLReference ref,
@NotNull URLReference ref,
boolean valid) {
super(element, range);
myReference = ref;
@@ -46,7 +48,9 @@ public class DependentNSReference extends BasicAttributeValueReference {
final String canonicalText = getCanonicalText();
final PsiFile file = ExternalResourceManager.getInstance().getResourceLocation(canonicalText, myElement.getContainingFile(), null);
if (file != null) return file;
return myReference.resolve();
PsiElement element = myReference.resolve();
if (element == null && !myForceFetchResultValid && !XmlUtil.isUrlText(canonicalText, myElement.getProject())) return myElement; // file reference will highlight it
return element;
}
@Override
@@ -63,4 +67,9 @@ public class DependentNSReference extends BasicAttributeValueReference {
public boolean isForceFetchResultValid() {
return myForceFetchResultValid;
}
@NotNull
public URLReference getNamespaceReference() {
return myReference;
}
}
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.impl.source.resolve.reference.impl.providers;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
@@ -22,6 +23,9 @@ import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiReferenceProvider;
import com.intellij.psi.filters.ElementFilter;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.ProcessingContext;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xml.util.XmlUtil;
@@ -60,7 +64,7 @@ public class URIReferenceProvider extends PsiReferenceProvider {
@NotNull
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull final ProcessingContext context) {
final String text = element.getText();
String s = StringUtil.stripQuotesAroundValue(text);
String s = StringUtil.unquoteString(text);
final PsiElement parent = element.getParent();
if (parent instanceof XmlAttribute &&
@@ -72,14 +76,37 @@ public class URIReferenceProvider extends PsiReferenceProvider {
while(tokenizer.hasMoreElements()) {
final String namespace = tokenizer.nextToken();
int offset = text.indexOf(namespace);
final URLReference urlReference = new URLReference(element, new TextRange(offset, offset + namespace.length()), true);
TextRange range = new TextRange(offset, offset + namespace.length());
final URLReference urlReference = new URLReference(element, range, true) {
@NotNull
@Override
public Object[] getVariants() {
XmlTag tag = (XmlTag)parent.getParent();
XmlAttribute[] attributes = tag.getAttributes();
return ContainerUtil.mapNotNull(attributes, new Function<XmlAttribute, Object>() {
@Override
public Object fun(final XmlAttribute attribute) {
final String attributeValue = attribute.getValue();
return attributeValue != null &&
attribute.isNamespaceDeclaration() &&
ContainerUtil.find(refs, new Condition<PsiReference>() {
@Override
public boolean value(PsiReference ref) {
return ref.getCanonicalText().equals(attributeValue);
}
}) == null ? attributeValue + " " : null;
}
}, ArrayUtil.EMPTY_OBJECT_ARRAY);
}
};
refs.add(urlReference);
if (!tokenizer.hasMoreElements()) break;
String url = tokenizer.nextToken();
offset = text.indexOf(url);
if (XmlUtil.isUrlText(url, element.getProject())) refs.add(new DependentNSReference(element, new TextRange(offset,offset + url.length()), urlReference));
else {
refs.add(new DependentNSReference(element, new TextRange(offset,offset + url.length()), urlReference));
if (!XmlUtil.isUrlText(url, element.getProject())) {
ContainerUtil.addAll(refs, new FileReferenceSet(url, element, offset, this, false).getAllReferences());
}
}
@@ -94,6 +121,7 @@ public class URIReferenceProvider extends PsiReferenceProvider {
return new FileReferenceSet(s,element,text.indexOf(s), this,true).getAllReferences();
}
static PsiReference getUrlReference(PsiElement element, String s) {
PsiElement parent = element.getParent();
if (XmlUtil.isUrlText(s, element.getProject()) ||
@@ -106,7 +134,7 @@ public class URIReferenceProvider extends PsiReferenceProvider {
if (!s.startsWith(XmlUtil.TAG_DIR_NS_PREFIX)) {
boolean namespaceSoftRef = parent instanceof XmlAttribute &&
NAMESPACE_ATTR_NAME.equals(((XmlAttribute)parent).getName()) &&
((XmlAttribute)parent).getParent().getAttributeValue("schemaLocation") != null;
((XmlAttribute)parent).getParent().getAttributeValue(XmlUtil.SCHEMA_LOCATION_ATT) != null;
if (!namespaceSoftRef && parent instanceof XmlAttribute && ((XmlAttribute)parent).isNamespaceDeclaration()) {
namespaceSoftRef = parent.getContainingFile().getContext() != null;
}
@@ -20,6 +20,7 @@ import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.xml.XmlFile;
@@ -36,10 +37,7 @@ import com.intellij.xml.util.XmlUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.File;
import java.io.IOException;
import java.io.*;
import java.util.*;
/**
@@ -50,17 +48,27 @@ public class XmlNamespaceIndex extends XmlIndex<XsdNamespaceBuilder> {
@Nullable
public static String getNamespace(@NotNull VirtualFile file, final Project project, PsiFile context) {
if (DumbService.isDumb(project) || (context != null && XmlUtil.isStubBuilding())) {
try {
return XsdNamespaceBuilder.computeNamespace(file.getInputStream());
}
catch (IOException e) {
return null;
}
return computeNamespace(file);
}
final List<XsdNamespaceBuilder> list = FileBasedIndex.getInstance().getValues(NAME, file.getUrl(), createFilter(project));
return list.size() == 0 ? null : list.get(0).getNamespace();
}
@Nullable
public static String computeNamespace(@NotNull VirtualFile file) {
InputStream stream = null;
try {
stream = file.getInputStream();
return XsdNamespaceBuilder.computeNamespace(stream);
}
catch (IOException e) {
return null;
}
finally {
StreamUtil.closeStream(stream);
}
}
public static List<IndexedRelevantResource<String, XsdNamespaceBuilder>> getResourcesByNamespace(String namespace,
@NotNull Project project,
@Nullable Module module) {