# ---------------------------------------------------------------------
if [ -z "$IDEA_JDK" ]; then
IDEA_JDK=$JDK_HOME
+ if [ -z "$IDEA_JDK" -a -e "$JAVA_HOME/lib/tools.jar" ]; then
+ IDEA_JDK=$JAVA_HOME
+ fi
+ if [ -z "$IDEA_JDK" ]; then
+ # Try to get the jdk path from java binary path
+ JAVA_BIN_PATH=`which java`
+ if [ -n "$JAVA_BIN_PATH" ]; then
+ JAVA_LOCATION=`readlink -f $JAVA_BIN_PATH | xargs dirname | xargs dirname | xargs dirname`
+ if [ -x "$JAVA_LOCATION/bin/java" -a -e "$JAVA_LOCATION/lib/tools.jar" ]; then
+ IDEA_JDK=$JAVA_LOCATION
+ fi
+ fi
+ fi
if [ -z "$IDEA_JDK" ]; then
echo ERROR: cannot start IntelliJ IDEA.
echo No JDK found to run IDEA. Please validate either IDEA_JDK or JDK_HOME points to valid JDK installation
package com.intellij.compiler.actions;
import com.intellij.history.LocalHistory;
-import com.intellij.history.LocalHistoryConfiguration;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
protected void doAction(DataContext dataContext, final Project project) {
CompilerManager.getInstance(project).rebuild(new CompileStatusNotification() {
public void finished(boolean aborted, int errors, int warnings, final CompileContext compileContext) {
- if (!aborted && LocalHistoryConfiguration.getInstance().ADD_LABEL_ON_PROJECT_COMPILATION) {
- String text = getTemplatePresentation().getText();
- if (!project.isDisposed()) {
- LocalHistory.putSystemLabel(project, errors == 0
- ? CompilerBundle.message("rebuild.lvcs.label.no.errors", text)
- : CompilerBundle.message("rebuild.lvcs.label.with.errors", text));
- }
- }
+ if (aborted) return;
+
+ String text = getTemplatePresentation().getText();
+ LocalHistory.getInstance().putSystemLabel(project, errors == 0
+ ? CompilerBundle.message("rebuild.lvcs.label.no.errors", text)
+ : CompilerBundle.message("rebuild.lvcs.label.with.errors", text));
}
});
}
if (file.getFileSystem() instanceof LocalFileSystem) {
if (file.isDirectory()) {
if (dbOnly) {
- for (VirtualFile child : ((NewVirtualFile)file).getInDbChildren()) {
- if (NullVirtualFile.INSTANCE != child) {
- processRecursively(child, true, processor);
- }
+ for (VirtualFile child : ((NewVirtualFile)file).iterInDbChildren()) {
+ processRecursively(child, true, processor);
}
}
else {
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.JavaPatchableProgramRunner;
import com.intellij.execution.ui.RunContentDescriptor;
-import com.intellij.history.LocalHistory;
-import com.intellij.history.LocalHistoryConfiguration;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
protected RunContentDescriptor doExecute(final Project project, final Executor executor, final RunProfileState state, final RunContentDescriptor contentToReuse,
final ExecutionEnvironment env) throws ExecutionException {
FileDocumentManager.getInstance().saveAllDocuments();
+ return createContentDescriptor(project, executor, state, contentToReuse, env);
+ }
- if (LocalHistoryConfiguration.getInstance().ADD_LABEL_ON_RUNNING) {
- final String name = env.getRunProfile().getName();
- final String label = state instanceof RemoteState
- ? DebuggerBundle.message("debugger.runner.vcs.label.remote.debug", name)
- : DebuggerBundle.message("debugger.runner.vcs.label.debugging", name);
- LocalHistory.putSystemLabel(project, label);
- }
+ @Override
+ protected String getLocalHistoryLabel(RunProfile profile, RunProfileState state) {
+ final String name = profile.getName();
+ return state instanceof RemoteState
+ ? DebuggerBundle.message("debugger.runner.vcs.label.remote.debug", name)
+ : DebuggerBundle.message("debugger.runner.vcs.label.debugging", name);
- return createContentDescriptor(project, executor, state, contentToReuse, env);
}
@Nullable
public void handleInsert(InsertionContext context, LookupElementDecorator<LookupItem> item) {
@SuppressWarnings({"unchecked"}) final LookupItem<PsiClass> delegate = item.getDelegate();
- delegate.handleInsert(context);
insertParentheses(context, delegate, delegate.getObject());
+ DefaultInsertHandler.addImportForItem(context.getFile(), context.getStartOffset(), delegate);
+
final PsiElement position = SmartCompletionDecorator.getPosition(context, delegate);
final PsiExpression enclosing = PsiTreeUtil.getContextOfType(position, PsiExpression.class, true);
}
public static void insertParentheses(InsertionContext context, LookupItem delegate, final PsiClass psiClass) {
- PsiDocumentManager.getInstance(context.getProject()).doPostponedOperationsAndUnblockDocument(context.getEditor().getDocument());
-
final PsiElement place = context.getFile().findElementAt(context.getStartOffset());
final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(context.getProject()).getResolveHelper();
assert place != null;
final boolean needLeftParenth = isToInsertParenth();
final boolean hasParams = needLeftParenth && hasParams();
- if (CompletionUtil.isOverwrite(item, completionChar))
+ if (CompletionUtil.isOverwrite(item, completionChar)) {
removeEndOfIdentifier(needLeftParenth && hasParams);
- else if(myContext.getOffsetMap().getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET) != myContext.getSelectionEndOffset())
+ }
+ else if(myContext.getOffsetMap().getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET) != myContext.getSelectionEndOffset()) {
JavaCompletionUtil.resetParensInfo(context.getOffsetMap());
+ }
handleParenses(hasParams, needLeftParenth, tailType);
handleBrackets();
}
}
- private boolean isToInsertParenth(){
+ protected boolean isToInsertParenth(){
return insertingAnnotationWithParameters();
}
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PatternCondition;
-import static com.intellij.patterns.PsiJavaPatterns.*;
import com.intellij.patterns.PsiNameValuePairPattern;
import com.intellij.psi.*;
import com.intellij.psi.filters.*;
import java.util.LinkedHashSet;
import java.util.Set;
+import static com.intellij.patterns.PsiJavaPatterns.*;
+
/**
* @author peter
*/
@Nullable
private 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);
+ 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)) {
return new AndFilter(ElementClassFilter.CLASS, new NotFilter(new AssignableFromContextFilter()));
}
new ParentElementFilter(new ClassFilter(PsiTryStatement.class)))
)));
public static final PsiJavaElementPattern.Capture<PsiElement> INSIDE_PARAMETER_LIST =
- PsiJavaPatterns.psiElement().withSuperParent(
- 2,
+ PsiJavaPatterns.psiElement().withParent(
psiElement(PsiJavaCodeReferenceElement.class).withParent(
psiElement(PsiTypeElement.class).withParent(PsiParameterList.class)));
public static final InsertHandler<JavaPsiClassReferenceElement> JAVA_CLASS_INSERT_HANDLER = new InsertHandler<JavaPsiClassReferenceElement>() {
public void handleInsert(final InsertionContext context, final JavaPsiClassReferenceElement item) {
if (completingRawConstructor(context, item)) {
- DefaultInsertHandler.NO_TAIL_HANDLER.handleInsert(context, item);
ConstructorInsertHandler.insertParentheses(context, item, item.getObject());
+ DefaultInsertHandler.addImportForItem(context.getFile(), context.getStartOffset(), item);
} else {
new DefaultInsertHandler().handleInsert(context, item);
}
JavaCompletionUtil.setShowFQN((LookupItem)item);
} else {
}
- ((LookupItem) item).setInsertHandler(DefaultInsertHandler.NO_TAIL_HANDLER);
result.addElement(decorate(LookupElementDecorator.withInsertHandler((LookupItem)item, ConstructorInsertHandler.INSTANCE), infos));
}
}
item.setAttribute(LookupItem.INDICATE_ANONYMOUS, "");
}
- item.setInsertHandler(DefaultInsertHandler.NO_TAIL_HANDLER);
result.addElement(decorate(type instanceof PsiClassType ? LookupElementDecorator.withInsertHandler(item, ConstructorInsertHandler.INSTANCE) : item, infos));
}
PsiElement element = file.findElementAt(context.getStartOffset());
if (element instanceof PsiIdentifier) {
element = element.getParent();
- while (element instanceof PsiJavaCodeReferenceElement || element instanceof PsiMethodCallExpression ||
+ while (element instanceof PsiJavaCodeReferenceElement || element instanceof PsiCall ||
element instanceof PsiThisExpression || element instanceof PsiSuperExpression ||
element instanceof PsiTypeElement ||
element instanceof PsiClassObjectAccessExpression) {
int newEnd = element.getTextRange().getEndOffset();
if (element instanceof PsiMethodCallExpression) {
- newEnd = ((PsiMethodCallExpression)element).getMethodExpression().getElement().getTextRange().getEndOffset();
+ newEnd = ((PsiMethodCallExpression)element).getMethodExpression().getTextRange().getEndOffset();
+ }
+ else if (element instanceof PsiNewExpression) {
+ final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)element).getClassReference();
+ if (classReference != null) {
+ newEnd = classReference.getTextRange().getEndOffset();
+ }
}
context.getOffsetMap().addOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET, newEnd);
element = element.getParent();
final Language ql = findLanguageByID("JPAQL");
final Language js = findLanguageByID("JavaScript");
if (ql == null || js == null) return;
+ final Language ecma4 = findLanguageByID("ECMA Script Level 4");
final MultiHostInjector myMultiHostInjector = new MultiHostInjector() {
public void getLanguagesToInject(@NotNull MultiHostRegistrar registrar, @NotNull PsiElement context) {
inject(host, placesToInject, js);
return;
}
+ if (ecma4 != null && "ecma4".equals(tag.getLocalName())) {
+ inject(host, placesToInject, ecma4);
+ return;
+ }
if ("jsprefix".equals(tag.getLocalName())) {
inject(host, placesToInject, js, "function foo(doc, window){", "}");
return;
}
protected void performRefactoring(UsageInfo[] usages) {
- LocalHistoryAction a = LocalHistory.startAction(myProject, getCommandName());
+ LocalHistoryAction a = LocalHistory.getInstance().startAction(getCommandName());
try {
doRefactoring(usages);
}
protected void performRefactoring(UsageInfo[] usages) {
if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, myTargetClass)) return;
- LocalHistoryAction a = LocalHistory.startAction(myProject, getCommandName());
+ LocalHistoryAction a = LocalHistory.getInstance().startAction(getCommandName());
try {
doRefactoring(usages);
}
private static PsiClass[] getTopLevelClasses(PsiElement element) {
while (true) {
if (element == null || element instanceof PsiFile) break;
- if (element instanceof PsiClass && (((PsiClass)element).getContainingClass() == null)) break;
- element = element.getContext();
+ if (element instanceof PsiClass && element.getParent() != null && (((PsiClass)element).getContainingClass() == null)) break;
+ element = element.getParent();
}
if (element instanceof PsiClassOwner) {
PsiClass[] classes = ((PsiClassOwner)element).getClasses();
private void doRefactoring() throws IncorrectOperationException {
- LocalHistoryAction a = LocalHistory.startAction(myProject, getCommandName());
+ LocalHistoryAction a = LocalHistory.getInstance().startAction(getCommandName());
PsiClass anInterface = null;
try {
anInterface = extractInterface(myTargetDir, myClass, myInterfaceName, mySelectedMembers, myJavaDocPolicy);
final PsiDirectory targetDirectory = dialog.getTargetDirectory();
final MemberInfo[] selectedMemberInfos = dialog.getSelectedMemberInfos();
final DocCommentPolicy javaDocPolicy = new DocCommentPolicy(dialog.getJavaDocPolicy());
- LocalHistoryAction a = LocalHistory.startAction(myProject, getCommandName(subclass, superclassName));
+ LocalHistoryAction a = LocalHistory.getInstance().startAction(getCommandName(subclass, superclassName));
try {
PsiClass superclass = null;
if (!myIsInnerClassNeeded) return;
PsiClass innerClass = myFactory.createClass(myInnerClassName);
- final PsiJavaCodeReferenceElement baseClassReferenceElement = myFactory.createClassReferenceElement(myBaseClass);
+ final PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(myBaseClass, myClass, PsiSubstitutor.EMPTY);
+ final PsiClassType superClassType = myFactory.createType(myBaseClass, superClassSubstitutor);
+ final PsiJavaCodeReferenceElement baseClassReferenceElement = myFactory.createReferenceElementByType(superClassType);
if (!myBaseClass.isInterface()) {
innerClass.getExtendsList().add(baseClassReferenceElement);
} else {
myEditor.getCaretModel().moveToLogicalPosition(pos);
}
- LocalHistoryAction a = LocalHistory.startAction(myProject, getCommandName());
+ LocalHistoryAction a = LocalHistory.getInstance().startAction(getCommandName());
try {
doRefactoring(usages);
}
ElementToWorkOn.processElementToWorkOn(editor, file, REFACTORING_NAME, getHelpID(), project, getElementProcessor(project, editor));
}
- protected boolean invokeImpl(Project project, final PsiLocalVariable localVariable, Editor editor) {
- final LocalToFieldHandler localToFieldHandler = new LocalToFieldHandler(project, true);
+ protected boolean invokeImpl(final Project project, final PsiLocalVariable localVariable, final Editor editor) {
+ final LocalToFieldHandler localToFieldHandler = new LocalToFieldHandler(project, true){
+ @Override
+ protected Settings showRefactoringDialog(PsiClass aClass,
+ PsiLocalVariable local,
+ PsiExpression[] occurences,
+ boolean isStatic) {
+ return IntroduceConstantHandler.this.showRefactoringDialog(project, editor, aClass, local.getInitializer(), local.getType(), occurences, null, null);
+ }
+ };
return localToFieldHandler.convertLocalToField(localVariable, editor);
}
}
}
- IntroduceConstantDialog dialog =
+ final IntroduceConstantDialog dialog =
new IntroduceConstantDialog(project, parentClass, expr, localVariable, false, occurences, getParentClass(),
new TypeSelectorManagerImpl(project, type, expr, occurences));
dialog.show();
return new ExpressionOccurenceManager(selectedExpr, parentClass, occurenceFilter, true);
}
- protected boolean invokeImpl(Project project, PsiLocalVariable localVariable, Editor editor) {
- LocalToFieldHandler localToFieldHandler = new LocalToFieldHandler(project, false);
+ protected boolean invokeImpl(final Project project, PsiLocalVariable localVariable, final Editor editor) {
+ LocalToFieldHandler localToFieldHandler = new LocalToFieldHandler(project, false){
+ @Override
+ protected Settings showRefactoringDialog(PsiClass aClass,
+ PsiLocalVariable local,
+ PsiExpression[] occurences,
+ boolean isStatic) {
+ final PsiStatement statement = PsiTreeUtil.getParentOfType(local, PsiStatement.class);
+ return IntroduceFieldHandler.this.showRefactoringDialog(project, editor, aClass, local.getInitializer(), local.getType(), occurences, statement, statement);
+ }
+ };
return localToFieldHandler.convertLocalToField(localVariable, editor);
}
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.RefactoringBundle;
-import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.refactoring.util.EnumConstantsUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import static com.intellij.refactoring.introduceField.BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR;
import static com.intellij.refactoring.introduceField.BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION;
-public class LocalToFieldHandler {
+public abstract class LocalToFieldHandler {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceField.LocalToFieldHandler");
private static final String REFACTORING_NAME = RefactoringBundle.message("convert.local.to.field.title");
myIsConstant = isConstant;
}
- protected BaseExpressionToFieldHandler.Settings showRefactoringDialog(PsiClass aClass, PsiLocalVariable local, PsiExpression[] occurences, boolean isStatic) {
- final String fieldName;
- final BaseExpressionToFieldHandler.InitializationPlace initializerPlace;
- final boolean declareFinal;
- @Modifier String fieldVisibility;
- final TypeSelectorManagerImpl typeSelectorManager = new TypeSelectorManagerImpl(myProject, local.getType(),
- occurences
- );
-
- final boolean annotateAsNonNls;
- final boolean introduceEnumConstant;
- if (myIsConstant) {
- IntroduceConstantDialog dialog = new IntroduceConstantDialog(myProject, aClass,
- local.getInitializer(), local, true, occurences, aClass, typeSelectorManager
- );
- dialog.show();
- if (!dialog.isOK()) return null;
- fieldName = dialog.getEnteredName();
- declareFinal = true;
- initializerPlace = IN_FIELD_DECLARATION;
- fieldVisibility = dialog.getFieldVisibility();
- annotateAsNonNls = dialog.isAnnotateAsNonNls();
- introduceEnumConstant = dialog.introduceEnumConstant();
- }
- else {
- PsiMethod method = PsiTreeUtil.getParentOfType(local, PsiMethod.class);
- IntroduceFieldDialog dialog = new IntroduceFieldDialog(myProject, aClass,
- local.getInitializer(), local,
- method != null && method.isConstructor(),
- true, isStatic,
- occurences.length, method != null, method != null,
- typeSelectorManager
- );
- dialog.show();
- if (!dialog.isOK()) return null;
- fieldName = dialog.getEnteredName();
- initializerPlace = dialog.getInitializerPlace();
- declareFinal = dialog.isDeclareFinal();
- fieldVisibility = dialog.getFieldVisibility();
- annotateAsNonNls = false;
- introduceEnumConstant = false;
- }
-
- return new BaseExpressionToFieldHandler.Settings(fieldName, true, isStatic, declareFinal, initializerPlace, fieldVisibility, local, null, true, new BaseExpressionToFieldHandler.TargetDestination(aClass), annotateAsNonNls,
- introduceEnumConstant);
- }
+ protected abstract BaseExpressionToFieldHandler.Settings showRefactoringDialog(PsiClass aClass, PsiLocalVariable local, PsiExpression[] occurences, boolean isStatic);
public boolean convertLocalToField(final PsiLocalVariable local, final Editor editor) {
PsiClass aClass;
protected void performRefactoring(UsageInfo[] usages) {
PsiManager psiManager = PsiManager.getInstance(myProject);
final PsiMigration psiMigration = JavaPsiFacade.getInstance(psiManager.getProject()).startMigration();
- LocalHistoryAction a = LocalHistory.startAction(myProject, getCommandName());
+ LocalHistoryAction a = LocalHistory.getInstance().startAction(getCommandName());
try {
for (int i = 0; i < myMigrationMap.getEntryCount(); i++) {
public void run() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
- LocalHistoryAction a = LocalHistory.startAction(project, commandDescription);
+ LocalHistoryAction a = LocalHistory.getInstance().startAction(commandDescription);
try {
rearrangeDirectoriesToTarget(directories, selectedTarget);
}
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2010 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.
LOG.assertTrue(newElement != null);
final PsiReference reference = moveRenameUsage.getReference();
if (reference != null) {
- reference.bindToElement(newElement);
+ try {
+ reference.bindToElement(newElement);
+ } catch (IncorrectOperationException e) {//
+ }
}
}
}
}
private static void replaceDuplicate(final Project project, final List<Match> duplicates, final PsiMethod method) {
- LocalHistoryAction a = LocalHistory.startAction(project, REFACTORING_NAME);
+ LocalHistoryAction a = LocalHistory.getInstance().startAction(REFACTORING_NAME);
try {
final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
if (progressIndicator != null && progressIndicator.isCanceled()) return;
--- /dev/null
+public enum ButtonKey {
+ CANCEL_ALL,
+ CANCEL_SELL;
+
+ public static final ButtonKey[] ARR = {CANCEL_ALL, CANCEL_S<caret>};
+}
\ No newline at end of file
--- /dev/null
+public enum ButtonKey {
+ CANCEL_ALL,
+ CANCEL_SELL;
+
+ public static final ButtonKey[] ARR = {CANCEL_ALL, CANCEL_SELL<caret>};
+}
\ No newline at end of file
--- /dev/null
+public class Foo {
+ Object foo(bo<caret>){ }
+}
--- /dev/null
+public class Foo {
+ Object foo(boolean <caret>){ }
+}
--- /dev/null
+public class Main {
+
+ public void main(String[] args) {
+ Aaaa a = new Bbbb(<caret>2);
+ }
+
+ class Aaaa {
+ int aaa;
+
+ Aaaa(int aaa) {
+ this.aaa = aaa;
+ }
+ }
+
+ class Bbbb extends Aaaa{
+ Bbbb(int aaa) {
+ super(aaa);
+ }
+ }
+
+}
--- /dev/null
+public class Main {
+
+ public void main(String[] args) {
+ Aaaa a = new B<caret>Aaaa(2);
+ }
+
+ class Aaaa {
+ int aaa;
+
+ Aaaa(int aaa) {
+ this.aaa = aaa;
+ }
+ }
+
+ class Bbbb extends Aaaa{
+ Bbbb(int aaa) {
+ super(aaa);
+ }
+ }
+
+}
--- /dev/null
+public class A {
+ public final MyIntf myDelegate = new MyIntf();
+
+ private class MyIntf implements Intf<Integer> {
+ public void method1(Integer t) {
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+public interface Intf<T> {
+ void method1(T t);
+}
\ No newline at end of file
--- /dev/null
+public class A implements Intf<Integer> {
+ public void method1(Integer t) {
+ }
+}
\ No newline at end of file
--- /dev/null
+public interface Intf<T> {
+ void method1(T t);
+}
\ No newline at end of file
public void testMethodParameterAnnotationClass() throws Throwable { doTest(); }
+ public void testEnumConstantFromEnumMember() throws Throwable { doTest(); }
+
+ public void testPrimitiveMethodParameter() throws Throwable { doTest(); }
+
}
checkResultByTestName();
}
+ public void testTabAfterNew() throws Exception {
+ configureByTestName();
+ select('\t');
+ checkResultByTestName();
+ }
+
private void doTest(boolean performAction, boolean selectItem) throws Exception {
configureByTestName();
if (performAction) {
new String[]{"getDate"}, ArrayUtil.EMPTY_STRING_ARRAY, false, false));
}
+ public void testTypeParametersSubstitution() throws Exception {
+ doTest(createPerformAction("A", "myDelegate", "MyIntf", "Intf", new int[]{}, ArrayUtil.EMPTY_STRING_ARRAY, true, false));
+ }
private PerformAction createPerformAction(
final String className, final String fieldName, final String innerClassName,
package com.intellij.execution.runners;
-import com.intellij.execution.ExecutionException;
-import com.intellij.execution.ExecutionManager;
-import com.intellij.execution.ExecutionResult;
-import com.intellij.execution.Executor;
+import com.intellij.execution.*;
import com.intellij.execution.configurations.*;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.history.LocalHistory;
-import com.intellij.history.LocalHistoryConfiguration;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.application.ApplicationManager;
if (callback != null) callback.processStarted(descriptor);
if (descriptor != null) {
- if (LocalHistoryConfiguration.getInstance().ADD_LABEL_ON_RUNNING) {
- LocalHistory.putSystemLabel(project, executor.getId() + " " + profile.getName());
- }
+ LocalHistory.getInstance().putSystemLabel(project, getLocalHistoryLabel(profile, state));
ExecutionManager.getInstance(project).getContentManager().showRunContent(executor, descriptor);
final ProcessHandler processHandler = descriptor.getProcessHandler();
protected abstract RunContentDescriptor doExecute(final Project project, final Executor executor, final RunProfileState state,
final RunContentDescriptor contentToReuse,
final ExecutionEnvironment env) throws ExecutionException;
+
+ protected String getLocalHistoryLabel(RunProfile profile, RunProfileState state) {
+ return ExecutionBundle.message("default.runner.start.action.label", profile.getName());
+ }
}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.execution.ui;
-
-import com.intellij.execution.filters.Filter;
-import com.intellij.execution.filters.HyperlinkInfo;
-import com.intellij.execution.process.ProcessHandler;
-import com.intellij.openapi.actionSystem.AnAction;
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.*;
-
-/**
- * @author Gregory.Shrago
- */
-public class ConsoleViewWrapper implements ConsoleView, ExecutionConsoleEx {
- private final ConsoleView myDelegate;
-
- public ConsoleViewWrapper(final ConsoleView delegate) {
- myDelegate = delegate;
- }
-
- public ConsoleView getDelegate() {
- return myDelegate;
- }
-
- public void dispose() {
- myDelegate.dispose();
- }
-
- public JComponent getComponent() {
- return myDelegate.getComponent();
- }
-
- public JComponent getPreferredFocusableComponent() {
- return myDelegate.getPreferredFocusableComponent();
- }
-
- public void print(String s, ConsoleViewContentType contentType) {
- myDelegate.print(s, contentType);
- }
-
- public void clear() {
- myDelegate.clear();
- }
-
- public void scrollTo(int offset) {
- myDelegate.scrollTo(offset);
- }
-
- public void attachToProcess(ProcessHandler processHandler) {
- myDelegate.attachToProcess(processHandler);
- }
-
- public void setOutputPaused(boolean value) {
- myDelegate.setOutputPaused(value);
- }
-
- public boolean isOutputPaused() {
- return myDelegate.isOutputPaused();
- }
-
- public boolean hasDeferredOutput() {
- return myDelegate.hasDeferredOutput();
- }
-
- public void performWhenNoDeferredOutput(Runnable runnable) {
- myDelegate.performWhenNoDeferredOutput(runnable);
- }
-
- public void setHelpId(String helpId) {
- myDelegate.setHelpId(helpId);
- }
-
- public void addMessageFilter(Filter filter) {
- myDelegate.addMessageFilter(filter);
- }
-
- public void printHyperlink(String hyperlinkText, HyperlinkInfo info) {
- myDelegate.printHyperlink(hyperlinkText, info);
- }
-
- public int getContentSize() {
- return myDelegate.getContentSize();
- }
-
- public boolean canPause() {
- return myDelegate.canPause();
- }
-
- public void buildUi(RunnerLayoutUi layoutUi) {
- if (myDelegate instanceof ExecutionConsoleEx) {
- ((ExecutionConsoleEx)myDelegate).buildUi(layoutUi);
- }
- }
-
-
- public String getExecutionConsoleId() {
- if (myDelegate instanceof ExecutionConsoleEx) {
- return ((ExecutionConsoleEx)myDelegate).getExecutionConsoleId();
- }
- return null;
- }
-
- @NotNull
- public AnAction[] createConsoleActions() {
- return myDelegate.createConsoleActions();
- }
-
-}
protected void run(Result result) throws Throwable {
LocalHistoryAction action = LocalHistoryAction.NULL;
try {
- action = LocalHistory.startAction(myProject, commandName);
+ action = LocalHistory.getInstance().startAction(commandName);
PsiElement[] psiElements = create(inputString);
myCreatedElements[0] = new SmartPsiElementPointer[psiElements.length];
public boolean isCollapsedByDefault(@NotNull ASTNode node) {
final FoldingBuilder builder = node.getUserData(FOLDING_BUILDER);
- return builder == null ? false : builder.isCollapsedByDefault(node);
+ return builder != null && builder.isCollapsedByDefault(node);
}
}
import com.intellij.lang.ASTNode;
import com.intellij.lang.Language;
-import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.editor.FoldingGroup;
import com.intellij.openapi.util.ProperTextRange;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
* Returns the folded text range.
* @return the folded text range.
*/
+ @NotNull
public TextRange getRange() {
- return getRange(myElement, myRange);
- }
-
- public static TextRange getRange(ASTNode node, TextRange range) {
- PsiElement element = node.getPsi();
- PsiFile containingFile = element.getContainingFile();
- InjectedLanguageManager injectedManager = InjectedLanguageManager.getInstance(containingFile.getProject());
- boolean isInjected = injectedManager.isInjectedFragment(containingFile);
- if (isInjected) {
- range = injectedManager.injectedToHost(element, range);
- }
- return range;
+ return myRange;
}
@Nullable
}
public void doCollectInformation(ProgressIndicator progress) {
- final boolean firstTime = myFile.getUserData(THE_FIRST_TIME) == null || myEditor.getUserData(THE_FIRST_TIME) == null;
+ final boolean firstTime = isFirstTime(myFile, myEditor, THE_FIRST_TIME);
Runnable runnable = CodeFoldingManager.getInstance(myProject).updateFoldRegionsAsync(myEditor, firstTime);
synchronized (this) {
myRunnable = runnable;
}
}
+ static boolean isFirstTime(PsiFile file, Editor editor, Key<Boolean> key) {
+ return file.getUserData(key) == null || editor.getUserData(key) == null;
+ }
+
+ static void clearFirstTimeFlag(PsiFile file, Editor editor, Key<Boolean> key) {
+ file.putUserData(key, Boolean.FALSE);
+ editor.putUserData(key, Boolean.FALSE);
+ }
+
public void doApplyInformationToEditor() {
Runnable runnable;
synchronized (this) {
try {
runnable.run();
}
- catch (IndexNotReadyException e) {
+ catch (IndexNotReadyException ignored) {
}
}
if (InjectedLanguageUtil.getTopLevelFile(myFile) == myFile) {
- myFile.putUserData(THE_FIRST_TIME, Boolean.FALSE);
- myEditor.putUserData(THE_FIRST_TIME, Boolean.FALSE);
+ clearFirstTimeFlag(myFile, myEditor, THE_FIRST_TIME);
}
}
}
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
class InjectedCodeFoldingPass extends TextEditorHighlightingPass implements DumbAware {
+ private static final Key<Boolean> THE_FIRST_TIME_KEY = Key.create("FirstInjectedFoldingPass");
private Runnable myRunnable;
private final Editor myEditor;
private final PsiFile myFile;
}
public void doCollectInformation(ProgressIndicator progress) {
- Runnable runnable = FoldingUpdate.updateInjectedFoldRegions(myEditor, myFile);
+ boolean firstTime = CodeFoldingPass.isFirstTime(myFile, myEditor, THE_FIRST_TIME_KEY);
+ Runnable runnable = FoldingUpdate.updateInjectedFoldRegions(myEditor, myFile, firstTime);
synchronized (this) {
myRunnable = runnable;
}
try {
runnable.run();
}
- catch (IndexNotReadyException e) {
+ catch (IndexNotReadyException ignored) {
}
+ CodeFoldingPass.clearFirstTimeFlag(myFile, myEditor, THE_FIRST_TIME_KEY);
}
}
}
\ No newline at end of file
final FoldRegion[] regions = editor.getFoldingModel().getAllFoldRegions();
editor.getFoldingModel().runBatchFoldingOperation(new Runnable() {
public void run() {
+ EditorFoldingInfo foldingInfo = EditorFoldingInfo.get(editor);
for (FoldRegion region : regions) {
- PsiElement element = EditorFoldingInfo.get(editor).getPsiElement(region);
+ PsiElement element = foldingInfo.getPsiElement(region);
if (element != null) {
region.setExpanded(!FoldingPolicy.isCollapseByDefault(element));
}
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.FoldRegion;
import com.intellij.openapi.editor.RangeMarker;
-import com.intellij.openapi.editor.impl.FoldRegionImpl;
+import com.intellij.openapi.editor.ex.FoldingModelEx;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.impl.text.CodeFoldingState;
import com.intellij.openapi.project.Project;
FoldRegion region = FoldingUtil.findFoldRegion(editor, marker.getStartOffset(), marker.getEndOffset());
if (region == null) {
String placeHolderText = myPlaceholderTexts.get(marker);
- region = new FoldRegionImpl(editor, marker.getStartOffset(), marker.getEndOffset(), placeHolderText, null); //may fail to add in case intersecting region exists
+ region = ((FoldingModelEx)editor.getFoldingModel()).createFoldRegion(marker.getStartOffset(), marker.getEndOffset(), placeHolderText, null);
+ //may fail to add in case intersecting region exists
if (!editor.getFoldingModel().addFoldRegion(region)) return;
}
package com.intellij.codeInsight.folding.impl;
import com.intellij.injected.editor.DocumentWindow;
+import com.intellij.injected.editor.EditorWindow;
import com.intellij.lang.Language;
import com.intellij.lang.folding.FoldingBuilder;
import com.intellij.lang.folding.FoldingDescriptor;
final TreeMap<PsiElement, FoldingDescriptor> elementsToFoldMap = new TreeMap<PsiElement, FoldingDescriptor>(COMPARE_BY_OFFSET);
getFoldingsFor(file instanceof PsiCompiledElement ? (PsiFile)((PsiCompiledElement)file).getMirror() : file, document, elementsToFoldMap, quick);
- final UpdateFoldRegionsOperation operation =
- new UpdateFoldRegionsOperation(project, editor, elementsToFoldMap, applyDefaultState, false);
+ final UpdateFoldRegionsOperation operation = new UpdateFoldRegionsOperation(project, editor, elementsToFoldMap, applyDefaultState, false);
Runnable runnable = new Runnable() {
public void run() {
editor.getFoldingModel().runBatchFoldingOperationDoNotCollapseCaret(operation);
private static final Key<Object> LAST_UPDATE_INJECTED_STAMP_KEY = Key.create("LAST_UPDATE_INJECTED_STAMP_KEY");
@Nullable
- public static Runnable updateInjectedFoldRegions(@NotNull final Editor editor, @NotNull PsiFile file) {
+ public static Runnable updateInjectedFoldRegions(@NotNull final Editor editor, @NotNull PsiFile file, final boolean applyDefaultState) {
if (file instanceof PsiCompiledElement) return null;
ApplicationManager.getApplication().assertReadAccessAllowed();
Object lastTimeStamp = editor.getUserData(LAST_UPDATE_INJECTED_STAMP_KEY);
if (lastTimeStamp instanceof Long && ((Long)lastTimeStamp).longValue() == timeStamp) return null;
- final TreeMap<PsiElement, FoldingDescriptor> elementsToFoldMap = new TreeMap<PsiElement, FoldingDescriptor>(COMPARE_BY_OFFSET);
-
List<DocumentWindow> injectedDocuments = InjectedLanguageUtil.getCachedInjectedDocuments(file);
if (injectedDocuments.isEmpty()) return null;
+ final List<EditorWindow> injectedEditors = new ArrayList<EditorWindow>();
+ final List<Map<PsiElement, FoldingDescriptor>> maps = new ArrayList<Map<PsiElement, FoldingDescriptor>>();
for (DocumentWindow injectedDocument : injectedDocuments) {
- PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(injectedDocument);
- if (psiFile == null || !psiFile.isValid() || !injectedDocument.isValid()) continue;
- getFoldingsFor(psiFile, injectedDocument, elementsToFoldMap, false);
+ PsiFile injectedFile = PsiDocumentManager.getInstance(project).getPsiFile(injectedDocument);
+ if (injectedFile == null || !injectedFile.isValid() || !injectedDocument.isValid()) continue;
+ Editor injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, injectedFile);
+ if (!(injectedEditor instanceof EditorWindow)) continue;
+
+ injectedEditors.add((EditorWindow)injectedEditor);
+ Map<PsiElement, FoldingDescriptor> map = new TreeMap<PsiElement, FoldingDescriptor>(COMPARE_BY_OFFSET);
+ maps.add(map);
+ getFoldingsFor(injectedFile, injectedDocument, map, false);
}
- final Runnable operation = new UpdateFoldRegionsOperation(project, editor, elementsToFoldMap, false, true);
+
+ final Runnable operation = new Runnable() {
+ public void run() {
+ for (int i = 0; i < injectedEditors.size(); i++) {
+ EditorWindow injectedEditor = injectedEditors.get(i);
+ Map<PsiElement, FoldingDescriptor> map = maps.get(i);
+ new UpdateFoldRegionsOperation(project, injectedEditor, map, applyDefaultState, true).run();
+ }
+ }
+ };
return new Runnable() {
public void run() {
editor.getFoldingModel().runBatchFoldingOperationDoNotCollapseCaret(operation);
};
}
- private static void getFoldingsFor(PsiFile file, Document document, TreeMap<PsiElement, FoldingDescriptor> elementsToFoldMap, boolean quick) {
+ private static void getFoldingsFor(PsiFile file, Document document, Map<PsiElement, FoldingDescriptor> elementsToFoldMap, boolean quick) {
final FileViewProvider viewProvider = file.getViewProvider();
for (final Language language : viewProvider.getLanguages()) {
final PsiFile psi = viewProvider.getPsi(language);
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.FoldRegion;
+import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.editor.ex.FoldingModelEx;
import com.intellij.openapi.util.TextRange;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Comparator;
+import java.util.Collections;
+import java.util.List;
class FoldingUtil {
private FoldingUtil() {}
}
public static FoldRegion[] getFoldRegionsAtOffset(Editor editor, int offset){
- ArrayList<FoldRegion> list = new ArrayList<FoldRegion>();
+ List<FoldRegion> list = new ArrayList<FoldRegion>();
FoldRegion[] allRegions = editor.getFoldingModel().getAllFoldRegions();
for (FoldRegion region : allRegions) {
if (region.getStartOffset() <= offset && offset <= region.getEndOffset()) {
}
FoldRegion[] regions = list.toArray(new FoldRegion[list.size()]);
- Arrays.sort(
- regions,
- new Comparator<FoldRegion>() {
- public int compare(FoldRegion region1, FoldRegion region2) {
- return region2.getStartOffset() - region1.getStartOffset();
- }
- }
- );
-
+ Arrays.sort(regions, Collections.reverseOrder(RangeMarker.BY_START_OFFSET));
return regions;
}
final int offset = editor.getCaretModel().getOffset();
return range.contains(offset) && range.getStartOffset() != offset;
}
-}
\ No newline at end of file
+}
import com.intellij.openapi.editor.FoldRegion;
import com.intellij.openapi.editor.FoldingGroup;
import com.intellij.openapi.editor.ex.FoldingModelEx;
-import com.intellij.openapi.editor.impl.FoldRegionImpl;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import java.util.List;
import java.util.Map;
-import java.util.TreeMap;
import static com.intellij.util.containers.CollectionFactory.arrayList;
import static com.intellij.util.containers.CollectionFactory.newTroveMap;
private final Project myProject;
private final Editor myEditor;
private final boolean myApplyDefaultState;
- private final TreeMap<PsiElement, FoldingDescriptor> myElementsToFoldMap;
+ private final Map<PsiElement, FoldingDescriptor> myElementsToFoldMap;
private final boolean myForInjected;
- UpdateFoldRegionsOperation(Project project, Editor editor, TreeMap<PsiElement, FoldingDescriptor> elementsToFoldMap, boolean applyDefaultState,
+ UpdateFoldRegionsOperation(Project project, Editor editor, Map<PsiElement, FoldingDescriptor> elementsToFoldMap, boolean applyDefaultState,
boolean forInjected) {
myProject = project;
myEditor = editor;
final FoldingDescriptor descriptor = entry.getValue();
FoldingGroup group = descriptor.getGroup();
TextRange range = descriptor.getRange();
- FoldRegion region = new FoldRegionImpl(myEditor, range.getStartOffset(), range.getEndOffset(), descriptor.getPlaceholderText(), group);
+ FoldRegion region = foldingModel.createFoldRegion(range.getStartOffset(), range.getEndOffset(), descriptor.getPlaceholderText(), group);
if (!foldingModel.addFoldRegion(region)) continue;
info.addRegion(region, descriptor);
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
-import java.awt.*;
-
public class BackspaceHandler extends EditorActionHandler {
private final EditorActionHandler myOriginalHandler;
final String prefix = lookup.getAdditionalPrefix();
if (prefix.length() > 0) {
lookup.setAdditionalPrefix(prefix.substring(0, prefix.length() - 1));
- if (lookup.isVisible()) {
- Point point = lookup.calculatePosition();
- Dimension preferredSize = lookup.getComponent().getPreferredSize();
- lookup.setBounds(point.x,point.y,preferredSize.width,preferredSize.height);
- lookup.getList().repaint();
- }
}
else{
lookup.hide();
myAdditionalPrefix = additionalPrefix;
myInitialPrefix = null;
markDirty();
- updateList();
+ refreshUi();
}
private void updateList() {
int shiftLow = layeredPane.getHeight() - (layeredPanePoint.y + dim.height);
int shiftHigh = layeredPanePoint.y - dim.height;
- myPositionedAbove = shiftLow < 0 && shiftLow < shiftHigh ? Boolean.TRUE : Boolean.FALSE;
-
- if (myPositionedAbove.booleanValue()){
+ if (!isPositionedAboveCaret()) {
+ myPositionedAbove = shiftLow < 0 && shiftLow < shiftHigh ? Boolean.TRUE : Boolean.FALSE;
+ }
+ if (isPositionedAboveCaret()) {
layeredPanePoint.y -= dim.height + myEditor.getLineHeight();
+ if (pos.line == 0) {
+ layeredPanePoint.y += 1;
+ //otherwise the lookup won't intersect with the editor and every editor's resize (e.g. after typing in console) will close the lookup
+ }
}
return layeredPanePoint;
}
}, "", editor.getDocument());
if (result == CharFilter.Result.ADD_TO_PREFIX){
- lookup.refreshUi();
+ return;
}
- else{
- if (result == CharFilter.Result.SELECT_ITEM_AND_FINISH_LOOKUP){
- LookupElement item = lookup.getCurrentItem();
- if (item != null){
- FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EDITING_COMPLETION_FINISH_BY_DOT_ETC);
- lookup.finishLookup(charTyped);
- return;
- }
- }
- lookup.hide();
- myOriginalHandler.execute(editor, charTyped, dataContext);
+ if (result == CharFilter.Result.SELECT_ITEM_AND_FINISH_LOOKUP){
+ LookupElement item = lookup.getCurrentItem();
+ if (item != null){
+ FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EDITING_COMPLETION_FINISH_BY_DOT_ETC);
+ lookup.finishLookup(charTyped);
+ return;
+ }
}
+
+ lookup.hide();
+ myOriginalHandler.execute(editor, charTyped, dataContext);
}
private static CharFilter.Result getLookupAction(final char charTyped, final LookupElement currentItem, final LookupImpl lookup) {
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.event.*;
import com.intellij.openapi.editor.ex.EditorEx;
+import com.intellij.openapi.editor.ex.FoldingModelEx;
import com.intellij.openapi.editor.ex.MarkupModelEx;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.editor.highlighter.HighlighterClient;
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
import com.intellij.openapi.editor.impl.EditorFactoryImpl;
-import com.intellij.openapi.editor.impl.FoldRegionImpl;
import com.intellij.openapi.editor.markup.HighlighterLayer;
import com.intellij.openapi.editor.markup.HighlighterTargetArea;
import com.intellij.openapi.editor.markup.RangeHighlighter;
if (oStart > 0) oStart--;
int oEnd = CharArrayUtil.shiftBackward(chars, document.getLineEndOffset(lEnd) - 1, " \t") + 1;
- toAdd.add(new FoldRegionImpl(myEditor, oStart, oEnd, prevFolding.getPlaceholderText(toFold), null));
+ FoldRegion region = ((FoldingModelEx)myEditor.getFoldingModel()).createFoldRegion(oStart, oEnd, prevFolding.getPlaceholderText(toFold), null);
+ toAdd.add(region);
}
}
((ExecutionConsoleEx)console).buildUi(myUi);
}
else {
- buildConsoleUiDefault(console);
+ buildConsoleUiDefault(myUi, console);
}
if (profile instanceof RunConfigurationBase) {
myManager.initLogConsoles((RunConfigurationBase)profile, myExecutionResult.getProcessHandler());
return contentDescriptor;
}
- private void buildConsoleUiDefault(final ExecutionConsole console) {
+ public static void buildConsoleUiDefault(RunnerLayoutUi ui, final ExecutionConsole console) {
DefaultActionGroup consoleActions = new DefaultActionGroup();
if (console instanceof ConsoleView) {
AnAction[] actions = ((ConsoleView)console).createConsoleActions();
}
}
- final Content consoleContent = myUi.createContent("Console", console.getComponent(), "Console",
+ final Content consoleContent = ui.createContent("Console", console.getComponent(), "Console",
IconLoader.getIcon("/debugger/console.png"),
console.getPreferredFocusableComponent());
consoleContent.setActions(consoleActions, ActionPlaces.UNKNOWN, console.getComponent());
- myUi.addContent(consoleContent, 0, PlaceInGrid.bottom, false);
+ ui.addContent(consoleContent, 0, PlaceInGrid.bottom, false);
}
public void addLogConsole(final String name, final String path, final long skippedContent) {
String actionName;
String dirPath = myDirectory.getVirtualFile().getPresentableUrl();
actionName = IdeBundle.message("progress.creating.directory", dirPath, File.separator, subDirName);
- action = LocalHistory.startAction(myProject, actionName);
+ action = LocalHistory.getInstance().startAction(actionName);
final PsiDirectory createdDir;
if (myIsDirectory) {
private final class MyDeleteElementProvider implements DeleteProvider {
public void deleteElement(final DataContext dataContext) {
- LocalHistoryAction a = LocalHistory.startAction(myProject, IdeBundle.message("progress.deleting"));
+ LocalHistoryAction a = LocalHistory.getInstance().startAction(IdeBundle.message("progress.deleting"));
try {
final PsiElement[] elements = getSelectedElements();
DeleteHandler.deletePsiElement(elements, myProject);
}
final PsiElement[] elements = validElements.toArray(new PsiElement[validElements.size()]);
- LocalHistoryAction a = LocalHistory.startAction(myProject, IdeBundle.message("progress.deleting"));
+ LocalHistoryAction a = LocalHistory.getInstance().startAction(IdeBundle.message("progress.deleting"));
try {
DeleteHandler.deletePsiElement(elements, myProject);
}
public final void deleteElement(final DataContext dataContext) {
final PsiElement aClass = getSelectedElement();
if (!canBeDeleted(aClass)) return;
- LocalHistoryAction a = LocalHistory.startAction(myProject, IdeBundle.message("progress.deleting.class", getQualifiedName(aClass)));
+ LocalHistoryAction a = LocalHistory.getInstance().startAction(IdeBundle.message("progress.deleting.class", getQualifiedName(aClass)));
try {
final PsiElement[] elements = new PsiElement[]{aClass};
DeleteHandler.deletePsiElement(elements, myProject);
}
final PsiElement[] elements = validElements.toArray(new PsiElement[validElements.size()]);
- LocalHistoryAction a = LocalHistory.startAction(myProject, IdeBundle.message("progress.deleting"));
+ LocalHistoryAction a = LocalHistory.getInstance().startAction(IdeBundle.message("progress.deleting"));
try {
DeleteHandler.deletePsiElement(elements, myProject);
}
}
final PsiElement[] elements = validElements.toArray(new PsiElement[validElements.size()]);
- LocalHistoryAction a = LocalHistory.startAction(myProject, IdeBundle.message("progress.deleting"));
+ LocalHistoryAction a = LocalHistory.getInstance().startAction(IdeBundle.message("progress.deleting"));
try {
DeleteHandler.deletePsiElement(elements, myProject);
}
if (elements == null) return;
Project project = PlatformDataKeys.PROJECT.getData(dataContext);
if (project == null) return;
- LocalHistoryAction a = LocalHistory.startAction(project, IdeBundle.message("progress.deleting"));
+ LocalHistoryAction a = LocalHistory.getInstance().startAction(IdeBundle.message("progress.deleting"));
try {
deletePsiElement(elements, project);
}
myCaretModelDelegate = new CaretModelWindow(myDelegate.getCaretModel(), this);
mySelectionModelDelegate = new SelectionModelWindow(myDelegate, myDocumentWindow,this);
myMarkupModelDelegate = new MarkupModelWindow((MarkupModelEx)myDelegate.getMarkupModel(), myDocumentWindow);
- myFoldingModelWindow = new FoldingModelWindow((FoldingModelEx)delegate.getFoldingModel(), documentWindow);
+ myFoldingModelWindow = new FoldingModelWindow((FoldingModelEx)delegate.getFoldingModel(), documentWindow, this);
}
public static void disposeInvalidEditors() {
package com.intellij.injected.editor;
import com.intellij.openapi.editor.FoldRegion;
-import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.openapi.editor.FoldingGroup;
import com.intellij.openapi.editor.ex.FoldingModelEx;
import com.intellij.openapi.editor.impl.FoldRegionImpl;
+import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.openapi.util.Key;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
+import java.util.*;
+import java.util.List;
/**
* @author cdr
public class FoldingModelWindow implements FoldingModelEx{
private final FoldingModelEx myDelegate;
private final DocumentWindow myDocumentWindow;
+ private final EditorWindow myEditorWindow;
- public FoldingModelWindow(FoldingModelEx delegate, DocumentWindow documentWindow) {
+ public FoldingModelWindow(@NotNull FoldingModelEx delegate, @NotNull DocumentWindow documentWindow, @NotNull EditorWindow editorWindow) {
myDelegate = delegate;
myDocumentWindow = documentWindow;
+ myEditorWindow = editorWindow;
}
public void setFoldingEnabled(boolean isEnabled) {
}
public FoldRegion[] getAllFoldRegionsIncludingInvalid() {
- return myDelegate.getAllFoldRegionsIncludingInvalid();
+ FoldRegion[] all = myDelegate.getAllFoldRegionsIncludingInvalid();
+ List<FoldRegion> result = new ArrayList<FoldRegion>();
+ for (FoldRegion region : all) {
+ FoldingRegionWindow window = region.getUserData(FOLD_REGION_WINDOW);
+ if (window != null && window.getEditor() == myEditorWindow) {
+ result.add(window);
+ }
+ }
+ return result.toArray(new FoldRegion[result.size()]);
}
public boolean intersectsRegion(int startOffset, int endOffset) {
}
public FoldRegion addFoldRegion(int startOffset, int endOffset, @NotNull String placeholderText) {
- return myDelegate.addFoldRegion(myDocumentWindow.injectedToHost(startOffset), myDocumentWindow.injectedToHost(endOffset), placeholderText);
+ FoldRegion region = createFoldRegion(startOffset, endOffset, placeholderText, null);
+ return addFoldRegion(region) ? region : null;
}
public boolean addFoldRegion(@NotNull final FoldRegion region) {
- return myDelegate.addFoldRegion(new FoldRegionImpl(region.getEditor(), myDocumentWindow.injectedToHost(region.getStartOffset()),
- myDocumentWindow.injectedToHost(region.getEndOffset()), region.getPlaceholderText(),
- region.getGroup()));
+ return myDelegate.addFoldRegion(((FoldingRegionWindow)region).getDelegate());
}
public void removeFoldRegion(@NotNull FoldRegion region) {
- myDelegate.removeFoldRegion(region);
+ myDelegate.removeFoldRegion(((FoldingRegionWindow)region).getDelegate());
}
@NotNull
public FoldRegion[] getAllFoldRegions() {
- return myDelegate.getAllFoldRegions();
+ FoldRegion[] all = myDelegate.getAllFoldRegions();
+ List<FoldRegion> result = new ArrayList<FoldRegion>();
+ for (FoldRegion region : all) {
+ FoldingRegionWindow window = region.getUserData(FOLD_REGION_WINDOW);
+ if (window != null && window.getEditor() == myEditorWindow) {
+ result.add(window);
+ }
+ }
+ return result.toArray(new FoldRegion[result.size()]);
}
public boolean isOffsetCollapsed(int offset) {
}
public FoldRegion getCollapsedRegionAtOffset(int offset) {
- return myDelegate.getCollapsedRegionAtOffset(myDocumentWindow.injectedToHost(offset));
+ FoldRegion host = myDelegate.getCollapsedRegionAtOffset(myDocumentWindow.injectedToHost(offset));
+ return host; //todo convert to window?
}
public void runBatchFoldingOperation(@NotNull Runnable operation) {
}
public FoldRegion fetchOutermost(int offset) {
- return null;
+ FoldRegion host = myDelegate.fetchOutermost(myDocumentWindow.injectedToHost(offset));
+ return host; //todo convert to window?
}
public int getLastCollapsedRegionBefore(int offset) {
- return -1;
+ return -1; //todo implement
}
public TextAttributes getPlaceholderAttributes() {
}
public FoldRegion[] fetchTopLevel() {
- return FoldRegion.EMPTY_ARRAY;
+ return FoldRegion.EMPTY_ARRAY; //todo implement
+ }
+
+ private static final Key<FoldingRegionWindow> FOLD_REGION_WINDOW = Key.create("FOLD_REGION_WINDOW");
+ public FoldRegion createFoldRegion(int startOffset, int endOffset, @NotNull String placeholder, FoldingGroup group) {
+ FoldRegion hostRegion = myDelegate.createFoldRegion(myDocumentWindow.injectedToHost(startOffset), myDocumentWindow.injectedToHost(endOffset), placeholder, group);
+ FoldingRegionWindow window = new FoldingRegionWindow(myDocumentWindow, myEditorWindow, (FoldRegionImpl)hostRegion);
+ hostRegion.putUserData(FOLD_REGION_WINDOW, window);
+ return window;
}
}
--- /dev/null
+/*
+ * Copyright 2000-2010 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.injected.editor;
+
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.FoldRegion;
+import com.intellij.openapi.editor.FoldingGroup;
+import com.intellij.openapi.editor.impl.FoldRegionImpl;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * User: cdr
+ */
+public class FoldingRegionWindow extends RangeMarkerWindow implements FoldRegion {
+ private final EditorWindow myEditorWindow;
+
+ private final FoldRegionImpl myHostRegion;
+
+ public FoldingRegionWindow(@NotNull DocumentWindow documentWindow, @NotNull EditorWindow editorWindow, @NotNull FoldRegionImpl hostRegion) {
+ super(documentWindow, hostRegion);
+ myEditorWindow = editorWindow;
+ myHostRegion = hostRegion;
+ }
+
+ public boolean isExpanded() {
+ return myHostRegion.isExpanded();
+ }
+
+ public void setExpanded(boolean expanded) {
+ myHostRegion.setExpanded(expanded);
+ }
+
+ @NotNull
+ public String getPlaceholderText() {
+ return myHostRegion.getPlaceholderText();
+ }
+
+ public Editor getEditor() {
+ return myEditorWindow;
+ }
+
+ public FoldingGroup getGroup() {
+ return myHostRegion.getGroup();
+ }
+
+ public FoldRegionImpl getDelegate() {
+ return myHostRegion;
+ }
+}
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
}
assert myPackageNameToDirsMap.keySet().size() == oldPackageNameToDirsMap.keySet().size();
- for (Map.Entry<String,List<VirtualFile>> entry : myPackageNameToDirsMap.entrySet()) {
+ for (Map.Entry<String, List<VirtualFile>> entry : myPackageNameToDirsMap.entrySet()) {
String packageName = entry.getKey();
List<VirtualFile> dirs = entry.getValue();
List<VirtualFile> dirs1 = oldPackageNameToDirsMap.get(packageName);
for (ExcludeFolder excludeRoot : excludeRoots) {
// Output paths should be excluded (if marked as such) regardless if they're under corresponding module's content root
if (excludeRoot.getFile() != null) {
- if (!contentRoot.getUrl().startsWith(excludeRoot.getUrl())) {
+ if (!FileUtil.startsWith(contentRoot.getUrl(), excludeRoot.getUrl())) {
if (isExcludeRootForModule(module, excludeRoot.getFile())) {
putForFileAndAllAncestors(result, excludeRoot.getFile(), excludeRoot.getUrl());
}
public Query<VirtualFile> search(@NotNull String packageName, boolean includeLibrarySources) {
List<VirtualFile> allDirs = doGetDirectoriesByPackageName(packageName);
- return new FilteredQuery<VirtualFile>(includeLibrarySources ? new CollectionQuery<VirtualFile>(allDirs) : createQuery(allDirs), IS_VALID);
+ return new FilteredQuery<VirtualFile>(includeLibrarySources ? new CollectionQuery<VirtualFile>(allDirs) : createQuery(allDirs),
+ IS_VALID);
}
}
VirtualFile parent = file.getParent();
if (parent == null) return;
- if (isIgnored(file)) return;
-
DirectoryInfo parentInfo = myDirToInfoMap.get(parent);
+
+ // fill info for all nested roots
+ for (Module eachModule : ModuleManager.getInstance(myProject).getModules()) {
+ for (ContentEntry eachRoot : getContentEntries(eachModule)) {
+ if (parentInfo != null && eachRoot == parentInfo.contentRoot) continue;
+
+ if (FileUtil.startsWith(eachRoot.getUrl(), file.getUrl())) {
+ String rel = FileUtil.getRelativePath(file.getUrl(), eachRoot.getUrl(), '/');
+ if (rel != null) {
+ VirtualFile f = file.findFileByRelativePath(rel);
+ fillMapWithModuleContent(f, eachModule, f);
+ }
+ }
+ }
+ }
+
if (parentInfo == null) return;
Module module = parentInfo.module;
}
}
- LocalHistoryAction action = LocalHistory.startAction(myProject, getCommandName());
+ LocalHistoryAction action = LocalHistory.getInstance().startAction(getCommandName());
final UsageInfo[] writableUsageInfos = usageInfoSet.toArray(new UsageInfo[usageInfoSet.size()]);
try {
}
if (file.isDirectory()) {
if (isMock(file) || myManagingFS.wereChildrenAccessed(file)) {
- final Collection<VirtualFile> children = (file instanceof NewVirtualFile)? ((NewVirtualFile)file).getInDbChildren() : Arrays.asList(file.getChildren());
+ final Iterable<VirtualFile> children = (file instanceof NewVirtualFile)? ((NewVirtualFile)file).iterInDbChildren() : Arrays.asList(file.getChildren());
for (VirtualFile child : children) {
- if (NullVirtualFile.INSTANCE != child) {
- invalidateIndices(child, markForReindex);
- }
+ invalidateIndices(child, markForReindex);
}
}
}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.
- */
-
-/*
- * @author max
- */
-package com.intellij.history;
-
-import com.intellij.openapi.vfs.VirtualFile;
-
-public class DeafLocalHistory extends LocalHistory {
- public byte[] getByteContent(final VirtualFile f, final FileRevisionTimestampComparator c) {
- throw new UnsupportedOperationException();
- }
-
- public boolean hasUnavailableContent(final VirtualFile f) {
- return false;
- }
-
- public boolean isUnderControl(final VirtualFile f) {
- return false;
- }
-
- public Label putSystemLabel(final String name, final int color) {
- return Label.NULL_INSTANCE;
- }
-
- public Label putUserLabel(final VirtualFile f, final String name) {
- return Label.NULL_INSTANCE;
- }
-
- public Label putUserLabel(final String name) {
- return Label.NULL_INSTANCE;
- }
-
- public LocalHistoryAction startAction(final String name) {
- return LocalHistoryAction.NULL;
- }
-
- public void save() {
- }
-}
package com.intellij.history;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.SettingsSavingComponent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
-public abstract class LocalHistory implements SettingsSavingComponent {
- public static LocalHistoryAction startAction(Project p, String name) {
- return getInstance(p).startAction(name);
- }
-
- public static Label putUserLabel(Project p, String name) {
- return getInstance(p).putUserLabel(name);
- }
-
- public static Label putUserLabel(Project p, VirtualFile f, String name) {
- return getInstance(p).putUserLabel(f, name);
- }
-
- public static Label putSystemLabel(Project p, String name) {
- return getInstance(p).putSystemLabel(name);
- }
-
- public static Label putSystemLabel(Project p, String name, int color) {
- return getInstance(p).putSystemLabel(name, color);
- }
-
- public static byte[] getByteContent(Project p, VirtualFile f, FileRevisionTimestampComparator c) {
- return getInstance(p).getByteContent(f, c);
- }
-
- public static boolean isUnderControl(Project p, VirtualFile f) {
- return getInstance(p).isUnderControl(f);
- }
-
- public static boolean hasUnavailableContent(Project p, VirtualFile f) {
- return getInstance(p).hasUnavailableContent(f);
- }
-
- public static LocalHistory getInstance(Project p) {
- return p.getComponent(LocalHistory.class);
+public abstract class LocalHistory {
+ public static LocalHistory getInstance() {
+ return ApplicationManager.getApplication().getComponent(LocalHistory.class);
}
public abstract LocalHistoryAction startAction(String name);
- public abstract Label putUserLabel(String name);
-
- public abstract Label putUserLabel(VirtualFile f, String name);
-
- public abstract Label putSystemLabel(String name, int color);
+ public abstract Label putSystemLabel(Project p, String name, int color);
- public Label putSystemLabel(String name) {
- return putSystemLabel(name, -1);
+ public Label putSystemLabel(Project p, String name) {
+ return putSystemLabel(p, name, -1);
}
+ public abstract Label putUserLabel(Project p, String name);
+
public abstract byte[] getByteContent(VirtualFile f, FileRevisionTimestampComparator c);
public abstract boolean isUnderControl(VirtualFile f);
-
- public abstract boolean hasUnavailableContent(VirtualFile f);
}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.history;
-
-import com.intellij.openapi.components.PersistentStateComponent;
-import com.intellij.openapi.components.ServiceManager;
-import com.intellij.openapi.components.State;
-import com.intellij.openapi.components.Storage;
-import com.intellij.util.xmlb.XmlSerializerUtil;
-
-@State(
- name = "LocalHistoryConfiguration",
- storages = {
- @Storage(
- id ="other",
- file = "$APP_CONFIG$/other.xml"
- )}
-)
-public class LocalHistoryConfiguration implements PersistentStateComponent<LocalHistoryConfiguration> {
- private static final long DEFAULT_PURGING_PERIOD = 1000 * 60 * 60 * 24 * 3; // 3 days
-
- public long PURGE_PERIOD = DEFAULT_PURGING_PERIOD;
-
- public boolean ADD_LABEL_ON_PROJECT_OPEN = true;
- public boolean ADD_LABEL_ON_PROJECT_COMPILATION = true;
- public boolean ADD_LABEL_ON_FILE_PACKAGE_COMPILATION = true;
- public boolean ADD_LABEL_ON_PROJECT_MAKE = true;
- public boolean ADD_LABEL_ON_RUNNING = true;
- public boolean ADD_LABEL_ON_DEBUGGING = true;
- public boolean ADD_LABEL_ON_UNIT_TEST_PASSED = true;
- public boolean ADD_LABEL_ON_UNIT_TEST_FAILED = true;
-
- public boolean SHOW_CHANGES_ONLY = false;
-
- public static LocalHistoryConfiguration getInstance() {
- return ServiceManager.getService(LocalHistoryConfiguration.class);
- }
-
- public LocalHistoryConfiguration getState() {
- return this;
- }
-
- public void loadState(final LocalHistoryConfiguration state) {
- XmlSerializerUtil.copyBean(state, this);
- }
-}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.openapi.localVcs;
-
-import com.intellij.history.LocalHistoryConfiguration;
-import com.intellij.openapi.components.SettingsSavingComponent;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * @deprecated use LocalHistory instead
- */
-public abstract class LocalVcs implements SettingsSavingComponent {
- public static LocalVcs getInstance(Project project) {
- return project.getComponent(LocalVcs.class);
- }
-
- public abstract Project getProject();
-
- public abstract String[] getRootPaths();
-
- @Nullable
- public abstract LvcsFile findFile(String filePath);
-
- @Nullable
- public abstract LvcsFile findFile(String filePath, boolean ignoreDeleted);
-
- @Nullable
- public abstract LvcsFileRevision findFileRevisionByDate(final String filePath, long date);
-
- @Nullable
- public abstract LvcsDirectory findDirectory(String dirPath);
-
- @Nullable
- public abstract LvcsDirectory findDirectory(String dirPath, boolean ignoreDeleted);
-
- public abstract LvcsLabel addLabel(String name, String path);
-
- public abstract LvcsLabel addLabel(byte type, String name, String path);
-
- public abstract LvcsAction startAction(String action, String path, boolean isExternalChanges);
-
- public abstract LvcsRevision[] getRevisions(String path, LvcsLabel label);
-
- public abstract LvcsRevision[] getRevisions(LvcsLabel label1, LvcsLabel label2);
-
- public abstract boolean isUnderVcs(VirtualFile file);
-
- public abstract boolean isAvailable();
-
- public abstract LocalVcsPurgingProvider getLocalVcsPurgingProvider();
-
- public abstract LvcsLabel[] getAllLabels();
-
- public abstract void addLvcsLabelListener(LvcsLabelListener listener);
-
- public abstract void removeLvcsLabelListener(LvcsLabelListener listener);
-
- public abstract LocalHistoryConfiguration getConfiguration();
-}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.openapi.localVcs;
-
-/**
- * @deprecated use LocalHistory instead
- */
-public interface LocalVcsItemsLocker {
- boolean itemCanBePurged(LvcsRevision lvcsObject);
-}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.openapi.localVcs;
-
-/**
- * @deprecated use LocalHistory instead
- */
-public interface LocalVcsPurgingProvider {
- void registerLocker(LocalVcsItemsLocker locker);
- void unregisterLocker(LocalVcsItemsLocker locker);
-
- boolean itemCanBePurged(LvcsRevision lvcsRevisionFor);
-}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.openapi.localVcs;
-
-import com.intellij.openapi.project.Project;
-
-/**
- * @deprecated use LocalHistory instead
- */
-public abstract class LocalVcsServices {
- public static LocalVcsServices getInstance(Project project) {
- return project.getComponent(LocalVcsServices.class);
- }
-
- public abstract LocalVcsItemsLocker getUpToDateRevisionProvider();
-}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.openapi.localVcs;
-
-import com.intellij.history.LocalHistoryAction;
-
-
-/**
- * @deprecated see LocalHistoryAction
- */
-public interface LvcsAction extends LocalHistoryAction {
- LvcsAction EMPTY = new LvcsAction() {
- public void finish() {
- }
-
- public String getName() {
- return "";
- }
- };
-
- void finish();
-
- String getName();
-}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.openapi.localVcs;
-
-import java.util.Comparator;
-
-/**
- * @deprecated use LocalHistory instead
- */
-public class LvcsComparator implements Comparator{
-
- public static final Comparator INSTANCE = new LvcsComparator();
-
- private LvcsComparator(){
-
- }
-
- public int compare(Object obj1, Object obj2) {
- if (obj1 instanceof LvcsRevision){
- if (obj2 instanceof LvcsRevision)
- return ((LvcsRevision)obj1).compareTo((LvcsRevision)obj2);
- else if (obj2 instanceof LvcsLabel)
- return ((LvcsRevision)obj1).compareTo((LvcsLabel)obj2);
- } else if (obj1 instanceof LvcsLabel)
- if (obj2 instanceof LvcsRevision)
- return ((LvcsLabel)obj1).compareTo((LvcsRevision)obj2);
- else if (obj2 instanceof LvcsLabel)
- return ((LvcsLabel)obj1).compareTo((LvcsLabel)obj2);
-
- throw new RuntimeException("Cannot compare " + obj1 + " and " + obj2);
- }
-}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.openapi.localVcs;
-
-import com.intellij.openapi.vfs.VirtualFile;
-
-/**
- * @deprecated use LocalHistory instead
- */
-public interface LvcsDirectory extends LvcsObject {
- LvcsFile[] getFiles();
- LvcsFile[] getFiles(LvcsLabel label);
-
- LvcsDirectory[] getDirectories();
- LvcsDirectory[] getDirectories(LvcsLabel label);
-
- LvcsObject[] getChildren();
- LvcsObject[] getChildren(LvcsLabel label);
-
- LvcsDirectory addDirectory(String name, VirtualFile onDisk);
-
- LvcsFile addFile(String name, VirtualFileInfo virtualFileInfo);
-}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.openapi.localVcs;
-
-/**
- * @deprecated use LocalHistory instead
- */
-public interface LvcsDirectoryRevision extends LvcsRevision {
- LvcsDirectoryRevision getParent();
-
- LvcsFileRevision[] getFiles();
- LvcsDirectoryRevision[] getDirectories();
-
- LvcsRevision[] getChildren();
-}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.openapi.localVcs;
-
-/**
- * @deprecated use LocalHistory instead
- */
-public interface LvcsFile extends LvcsObject {
- byte[] getByteContent();
- byte[] getByteContent(LvcsLabel label);
-
- void commit(VirtualFileInfo fileInfo);
- void commitRefactorings(byte[] newContent);
-
- long getByteLength(LvcsLabel label);
-
- long getTimeStamp();
-
- LvcsFileRevision getRevision();
-}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.openapi.localVcs;
-
-/**
- * @deprecated use LocalHistory instead
- */
-public interface LvcsFileRevision extends LvcsRevision {
- byte[] getByteContent();
- long getByteLength();
-
- LvcsFileRevision getLastSavedRevision();
-
- void markSaved();
-}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.openapi.localVcs;
-
-
-
-/**
- * @deprecated use LocalHistory instead
- */
-public interface LvcsLabel extends Comparable<LvcsLabel>{
- byte TYPE_BEFORE_ACTION = 1;
- byte TYPE_AFTER_ACTION = 2;
-
- byte TYPE_OTHER = 3;
- byte TYPE_TESTS_SUCCESSFUL = 4;
- byte TYPE_TESTS_FAILED = 5;
-
- byte TYPE_USER = 6;
-
- int getType();
- String getName();
- String getPath();
- long getDate();
- String getAction();
- int getVersionId();
-
- LvcsLabel getRecentChangesBeforeLabel( long date );
-
- int compareTo(LvcsRevision revision);
-}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.openapi.localVcs;
-
-/**
- * @deprecated use LocalHistory instead
- */
-public interface LvcsLabelListener {
- void labelAdded(LvcsLabel label);
- void labelDeleted(LvcsLabel label);
-}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.openapi.localVcs;
-
-import com.intellij.openapi.vfs.VirtualFile;
-
-/**
- * @deprecated use LocalHistory instead
- */
-public interface LvcsObject {
- LocalVcs getLocalVcs();
-
- LvcsRevision getRevision();
- LvcsRevision getRevision(LvcsLabel label);
-
- String getName();
- String getName(LvcsLabel label);
-
- String getAbsolutePath();
- String getAbsolutePath(LvcsLabel label);
-
- long getDate();
- long getDate(LvcsLabel label);
-
- boolean exists();
- boolean exists(LvcsLabel label);
-
- LvcsObject getParent();
- LvcsObject getParent(LvcsLabel label);
-
- void delete();
-
- void rename(String newName, VirtualFile file);
- void move(LvcsDirectory newParent, VirtualFile virtualFile);
-
- void scheduleForRemoval();
-}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.openapi.localVcs;
-
-import org.jetbrains.annotations.NonNls;
-
-/**
- * @deprecated use LocalHistory instead
- */
-public interface LvcsRevision extends Comparable{
- @NonNls String PROPERTY_UP_TO_DATE = "upToDate";
-
- String getName();
- String getAbsolutePath();
-
- long getDate();
- boolean isDeleted();
- boolean isPurged();
-
- int getId();
-
- LvcsObject getObject();
-
- LvcsRevision getNextRevision();
- LvcsRevision getPrevRevision();
-
- LvcsRevision getParentRevision();
-
- void setUpToDate(boolean value);
- boolean isUpToDate();
-
- /**
- * Returns a lable, which is associated with this revision. You can use this label to view the VCS
- * at the moment of revision creation. This label is not visible view LocalVcs.getLabels().
- */
- LvcsLabel getImplicitLabel();
-
- LvcsRevision findLatestRevision();
-
- LvcsRevision findNearestPreviousUpToDateRevision();
-
- int compareTo(LvcsLabel label);
-
- int compareTo(LvcsRevision label);
-
- long getCreationDate();
-
- int getLength();
-
- int getVersionId();
-
- int getVersion();
-
- boolean isScheduledForRemoval();
-
- boolean isTooLong();
-
- boolean hasContent();
-}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.openapi.localVcs;
-
-import java.io.IOException;
-
-/**
- * @deprecated use LocalHistory instead
- */
-public interface VirtualFileInfo {
- String getFilePath();
- long getFileTampStamp();
- byte[] getFileByteContent() throws IOException;
-
- boolean isDirectory();
-
- String getName();
-
- int getFileSize();
-
-}
+++ /dev/null
-<!--
- ~ Copyright 2000-2007 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.
- -->
-
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html><body bgcolor="white">
-Provides interfaces for working with IDEA's Local VCS.
-</body></html>
<orderEntry type="module" module-name="testFramework" scope="TEST" />
<orderEntry type="module" module-name="lvcs-api" />
<orderEntry type="library" scope="TEST" name="EasyMock" level="project" />
- <orderEntry type="module" module-name="platform-impl" />
+ <orderEntry type="library" name="jcip" level="project" />
+ <orderEntry type="library" name="commons-lang" level="project" />
<orderEntry type="module" module-name="lang-api" />
- <orderEntry type="module" module-name="lang-impl" />
+ <orderEntry type="module" module-name="platform-impl" />
</component>
<component name="copyright">
<Base>
import com.intellij.history.core.changes.ChangeVisitor;
import com.intellij.history.core.changes.ContentChange;
import com.intellij.history.core.storage.Content;
+import com.intellij.history.core.tree.Entry;
+import com.intellij.history.core.tree.RootEntry;
+import com.intellij.openapi.util.Pair;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
// Therefore we have to move along the changelist, revert only content changes
// and record file and changeset timestamps to call comparator with.
public class ByteContentRetriever extends ChangeSetsProcessor {
+ private final LocalHistoryFacade myVcs;
private final FileRevisionTimestampComparator myComparator;
private long myCurrentFileTimestamp;
private Content myCurrentFileContent;
- public ByteContentRetriever(LocalVcs vcs, String path, FileRevisionTimestampComparator c) {
- super(vcs, path);
+ public ByteContentRetriever(LocalHistoryFacade vcs, RootEntry root, String path, FileRevisionTimestampComparator c) {
+ super(path);
+ myVcs = vcs;
myComparator = c;
- myCurrentFileContent = myEntry.getContent();
- myCurrentFileTimestamp = myEntry.getTimestamp();
+ Entry entry = root.getEntry(path);
+ myCurrentFileContent = entry.getContent();
+ myCurrentFileTimestamp = entry.getTimestamp();
}
public byte[] getResult() {
try {
+ checkCurrentRevision(); // optimization: do not collect changes if current revision will do
process();
}
catch (ContentFoundException ignore) {
}
@Override
- protected List<Change> collectChanges() {
- try {
- final List<Change> result = new ArrayList<Change>();
+ protected Pair<String, List<ChangeSet>> collectChanges() {
+ final List<ChangeSet> result = new ArrayList<ChangeSet>();
- myVcs.acceptRead(new ChangeVisitor() {
- @Override
- public void begin(ChangeSet c) {
- if (c.affects(myEntry)) result.add(c);
- }
- });
+ myVcs.accept(new ChangeVisitor() {
+ @Override
+ public void begin(ChangeSet c) throws StopVisitingException {
+ if (c.affectsPath(myPath)) result.add(c);
+ }
+ });
- return result;
- }
- catch (IOException ex) {
- throw new RuntimeException(ex);
- }
+ return Pair.create(myPath, result);
}
@Override
protected void nothingToVisit() {
// visit current version
- doVisit();
+ checkCurrentRevision();
}
@Override
- protected void visitLabel(Change c) {
+ public void visit(ChangeSet changeSet) {
+ checkCurrentRevision();
+ recordContentAndTimestamp(changeSet);
}
@Override
- public void visitRegular(Change c) {
- doVisit();
- recordContentAndTimestamp(c);
+ protected void visitFirstAvailableNonCreational(ChangeSet changeSet) {
+ checkCurrentRevision();
}
- @Override
- protected void visitFirstAvailableNonCreational(Change c) {
- doVisit();
- }
-
- void doVisit() {
+ private void checkCurrentRevision() {
if (myComparator.isSuitable(myCurrentFileTimestamp)) {
throw new ContentFoundException();
}
}
- private void recordContentAndTimestamp(Change c) {
+ private void recordContentAndTimestamp(ChangeSet c) {
+ // todo what if the path is being changed during changes?
for (Change each : c.getChanges()) {
- if (!each.isFileContentChange()) continue;
- if (!each.affectsOnlyInside(myEntry)) continue;
-
+ if (!(each instanceof ContentChange)) continue;
ContentChange cc = (ContentChange)each;
+ if (!cc.affectsPath(myPath)) continue;
myCurrentFileTimestamp = cc.getOldTimestamp();
myCurrentFileContent = cc.getOldContent();
--- /dev/null
+/*
+ * Copyright 2000-2010 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.history.core;
+
+import com.intellij.history.core.changes.*;
+import com.intellij.psi.codeStyle.NameUtil;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.regex.Pattern;
+
+public class ChangeCollectingVisitor extends ChangeVisitor {
+ private String myPath;
+ private final String myProjectId;
+ private final Pattern myPattern;
+ private ChangeSet myCurrentChangeSet;
+ private boolean myExists = true;
+ private boolean myDoNotAddAnythingElseFromCurrentChangeSet = false;
+ private final LinkedHashSet<ChangeSet> myResult = new LinkedHashSet<ChangeSet>();
+
+ public ChangeCollectingVisitor(String path, String projectId, @Nullable String pattern) {
+ myPath = path;
+ myProjectId = projectId;
+ myPattern = pattern == null ? null : Pattern.compile(NameUtil.buildRegexp(pattern, 0, true, true), Pattern.CASE_INSENSITIVE);
+ }
+
+ public List<ChangeSet> getChanges() {
+ return new ArrayList<ChangeSet>(myResult);
+ }
+
+ public String getPath() {
+ return myPath;
+ }
+
+ @Override
+ public void begin(ChangeSet c) throws StopVisitingException {
+ myCurrentChangeSet = c;
+ }
+
+ @Override
+ public void end(ChangeSet c) throws StopVisitingException {
+ myCurrentChangeSet = null;
+ myDoNotAddAnythingElseFromCurrentChangeSet = false;
+ }
+
+ @Override
+ public void visit(PutLabelChange c) throws StopVisitingException {
+ doVisit(c);
+ }
+
+ @Override
+ public void visit(StructuralChange c) throws StopVisitingException {
+ doVisit(c);
+ }
+
+ private void doVisit(Change c) {
+ if (skippedDueToNonexistence(c)) return;
+ addIfAffectsAndRevert(c);
+ }
+
+ @Override
+ public void visit(CreateEntryChange c) throws StopVisitingException {
+ if (skippedDueToNonexistence(c)) return;
+ addIfAffectsAndRevert(c);
+ if (c.isCreationalFor(myPath)) myExists = false;
+ }
+
+ @Override
+ public void visit(DeleteChange c) throws StopVisitingException {
+ if (skippedDueToNonexistence(c)) {
+ if (c.isDeletionOf(myPath)) {
+ myExists = true;
+ myDoNotAddAnythingElseFromCurrentChangeSet = true;
+ }
+ return;
+ }
+ addIfAffectsAndRevert(c);
+ }
+
+ private void addIfAffectsAndRevert(Change c) {
+ if (!myDoNotAddAnythingElseFromCurrentChangeSet && (c.affectsPath(myPath) || c.affectsProject(myProjectId))) {
+ if (myPattern == null || c.affectsMatching(myPattern)) {
+ myResult.add(myCurrentChangeSet);
+ }
+ }
+ if (c instanceof StructuralChange) myPath = ((StructuralChange)c).revertPath(myPath);
+ }
+
+ private boolean skippedDueToNonexistence(Change c) {
+ if (myExists) return false;
+ if (c instanceof StructuralChange) myPath = ((StructuralChange)c).revertPath(myPath);
+ return true;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2009 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.history.core;
+
+import com.intellij.history.Clock;
+import com.intellij.history.core.changes.Change;
+import com.intellij.history.core.changes.ChangeSet;
+import com.intellij.history.core.changes.ChangeVisitor;
+import com.intellij.history.core.storage.Content;
+import com.intellij.openapi.application.Application;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.TestOnly;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class ChangeList {
+ private final ChangeListStorage myStorage;
+
+ private ChangeSetBlock myCurrentBlock;
+
+ private ChangeSet myCurrentChangeSet;
+ private int myChangeSetDepth;
+
+ private int myIntervalBetweenActivities = 12 * 60 * 60 * 1000; // one day
+
+ public ChangeList(ChangeListStorage storage) {
+ myStorage = storage;
+ myCurrentBlock = storage.createNewBlock();
+ }
+
+ public synchronized void save() {
+ flushChanges(true);
+ }
+
+ public synchronized void close() {
+ flushChanges(true);
+ myStorage.close();
+ }
+
+ public synchronized long nextId() {
+ return myStorage.nextId();
+ }
+
+ public synchronized void addChange(Change c) {
+ assert myChangeSetDepth != 0;
+ myCurrentChangeSet.addChange(c);
+ }
+
+ public synchronized void beginChangeSet() {
+ myChangeSetDepth++;
+ if (myChangeSetDepth > 1) return;
+
+ myCurrentChangeSet = new ChangeSet(myStorage.nextId(), Clock.getCurrentTimestamp());
+ myCurrentBlock.add(myCurrentChangeSet);
+ }
+
+ public synchronized boolean endChangeSet(String name) {
+ assert myChangeSetDepth > 0;
+
+ myChangeSetDepth--;
+ if (myChangeSetDepth > 0) return false;
+
+ if (myCurrentChangeSet.getChanges().isEmpty()) {
+ myCurrentBlock.removeLast();
+ return false;
+ }
+
+ myCurrentChangeSet.setName(name);
+ myCurrentChangeSet = null;
+
+ flushChanges(false);
+ return true;
+ }
+
+ @TestOnly
+ public List<ChangeSet> getChangesInTests() {
+ List<ChangeSet> result = new ArrayList<ChangeSet>();
+ for (ChangeSet each : iterChanges()) {
+ result.add(each);
+ }
+ return result;
+ }
+
+ public synchronized Iterable<ChangeSet> iterChanges() {
+ return new Iterable<ChangeSet>() {
+ public Iterator<ChangeSet> iterator() {
+ return new Iterator<ChangeSet>() {
+ private ChangeSetBlock currentBlock;
+ private Iterator<ChangeSet> currentIter;
+
+ private ChangeSet next = fetchNext();
+
+ public boolean hasNext() {
+ return next != null;
+ }
+
+ public ChangeSet next() {
+ ChangeSet result = next;
+ next = fetchNext();
+ return result;
+ }
+
+ private ChangeSet fetchNext() {
+ if (currentBlock == null) {
+ synchronized (ChangeList.this) {
+ currentBlock = myCurrentBlock;
+ List<ChangeSet> copy = new ArrayList<ChangeSet>(currentBlock.changes);
+ currentIter = ContainerUtil.iterateBackward(copy).iterator();
+ }
+ }
+ while (!currentIter.hasNext()) {
+ synchronized (ChangeList.this) {
+ currentBlock = myStorage.readPrevious(currentBlock);
+ }
+ if (currentBlock == null) return null;
+ currentIter = ContainerUtil.iterateBackward(currentBlock.changes).iterator();
+ }
+ return currentIter.next();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+ };
+ }
+
+ private void flushChanges(boolean force) {
+ if (myChangeSetDepth > 0) return;
+ if (myCurrentBlock.shouldFlush(force) || flushEveryChangeSetInTests()) {
+ myStorage.writeNextBlock(myCurrentBlock);
+ myCurrentBlock = myStorage.createNewBlock();
+ }
+ myStorage.flush();
+ }
+
+ private boolean flushEveryChangeSetInTests() {
+ Application app = ApplicationManager.getApplication();
+ return app == null || app.isUnitTestMode();
+ }
+
+ public void accept(ChangeVisitor v) {
+ try {
+ for (ChangeSet change : iterChanges()) {
+ change.accept(v);
+ }
+ }
+ catch (ChangeVisitor.StopVisitingException e) {
+ }
+ v.finished();
+ }
+
+ public synchronized void purgeObsolete(long period) {
+ List<Content> contentsToPurge = new ArrayList<Content>();
+
+ List<ChangeSetBlock> blocks = myStorage.purge(period, myIntervalBetweenActivities);
+ for (ChangeSetBlock each : blocks) {
+ for (ChangeSet changeSet : each.changes) {
+ contentsToPurge.addAll(changeSet.getContentsToPurge());
+ }
+ }
+
+ for (Content each : contentsToPurge) {
+ each.release();
+ }
+ }
+
+ @TestOnly
+ public void setIntervalBetweenActivities(int value) {
+ myIntervalBetweenActivities = value;
+ }
+}
\ No newline at end of file
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2010 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.
* limitations under the License.
*/
-package com.intellij.history.core.storage;
+package com.intellij.history.core;
-public interface IContentStorage {
- void save();
+import org.jetbrains.annotations.Nullable;
+import java.util.List;
+
+public interface ChangeListStorage {
void close();
- int store(byte[] content) throws BrokenStorageException;
+ long nextId();
+
+ ChangeSetBlock createNewBlock();
- byte[] load(int id) throws BrokenStorageException;
+ @Nullable
+ ChangeSetBlock readPrevious(ChangeSetBlock block);
- void remove(int id);
+ List<ChangeSetBlock> purge(long period, int intervalBetweenActivities);
- void setVersion(int version);
+ void writeNextBlock(ChangeSetBlock block);
- int getVersion();
-}
+ void flush();
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2000-2010 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.history.core;
+
+import com.intellij.history.core.changes.ChangeSet;
+import com.intellij.history.utils.LocalHistoryLog;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.newvfs.ManagingFS;
+import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
+import com.intellij.util.io.storage.AbstractStorage;
+
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ChangeListStorageImpl implements ChangeListStorage {
+ private static final int VERSION = 3;
+
+ private static final String STORAGE_FILE = "changes";
+
+ private final File myStorageDir;
+ private final LinkedStorage myStorage;
+
+ public ChangeListStorageImpl(File storageDir) {
+ myStorageDir = storageDir;
+ try {
+ myStorage = createStorage(myStorageDir);
+ }
+ catch (IOException e) {
+ throw handleError(e);
+ }
+ }
+
+ private static LinkedStorage createStorage(File storageDir) throws IOException {
+ String path = storageDir.getPath() + "/" + STORAGE_FILE;
+ LinkedStorage result = new LinkedStorage(path);
+
+ long fsTimestamp = ((PersistentFS)ManagingFS.getInstance()).getCreationTimestamp();
+
+ boolean versionMismatch = result.getVersion() != VERSION;
+ boolean timestampMismatch = result.getFSTimestamp() != fsTimestamp;
+ if (versionMismatch || timestampMismatch) {
+ if (versionMismatch) LocalHistoryLog.LOG.info("local history version mismatch, rebuilding...");
+ if (timestampMismatch) LocalHistoryLog.LOG.info("FS has been rebuild, rebuilding clearing local history...");
+ result.dispose();
+ if (!FileUtil.delete(storageDir)) {
+ throw new IOException("cannot clear storage dir: " + storageDir);
+ }
+ result = new LinkedStorage(path);
+ result.setVersion(VERSION);
+ result.setFSTimestamp(fsTimestamp);
+ }
+ return result;
+ }
+
+ private RuntimeException handleError(Throwable e) {
+ try {
+ if (myStorage != null) {
+ myStorage.setVersion(-1);
+ }
+ }
+ catch (Throwable ex) {
+ LocalHistoryLog.LOG.error("cannot mark storage as broken", ex);
+ }
+ throw new RuntimeException(e);
+ }
+
+ public synchronized void close() {
+ myStorage.dispose();
+ }
+
+ public synchronized long nextId() {
+ return myStorage.nextId();
+ }
+
+ public synchronized ChangeSetBlock createNewBlock() {
+ return new ChangeSetBlock(0);
+ }
+
+ public synchronized ChangeSetBlock readPrevious(ChangeSetBlock block) {
+ int prevId = block.id == 0 ? myStorage.getLastRecord() : myStorage.getPrevRecord(block.id);
+ if (prevId == 0) return null;
+ assert prevId != block.id;
+ return doReadBlock(prevId);
+ }
+
+ private ChangeSetBlock doReadBlock(int id) {
+ DataInputStream in = myStorage.readStream(id);
+ try {
+ try {
+ int size = in.readInt();
+ List<ChangeSet> changes = new ArrayList<ChangeSet>(size);
+ while (size-- > 0) {
+ changes.add(new ChangeSet(in));
+ }
+ return new ChangeSetBlock(id, changes);
+ }
+ finally {
+ in.close();
+ }
+ }
+ catch (Throwable e) {
+ throw handleError(e);
+ }
+ }
+
+ public synchronized void writeNextBlock(ChangeSetBlock block) {
+ try {
+ block.id = myStorage.createNextRecord();
+ AbstractStorage.StorageDataOutput out = myStorage.writeStream(block.id);
+ try {
+ out.writeInt(block.changes.size());
+ for (ChangeSet each : block.changes) {
+ each.write(out);
+ }
+ }
+ finally {
+ out.close();
+ }
+ }
+ catch (IOException e) {
+ throw handleError(e);
+ }
+ }
+
+ public synchronized List<ChangeSetBlock> purge(long period, int intervalBetweenActivities) {
+ List<ChangeSetBlock> result = new ArrayList<ChangeSetBlock>();
+ int each = findFirstObsoleteBlock(period, intervalBetweenActivities);
+ try {
+ while(each != 0) {
+ result.add(doReadBlock(each));
+ myStorage.deleteRecord(each);
+ each = myStorage.getPrevRecord(each);
+ }
+ }
+ catch (IOException e) {
+ throw handleError(e);
+ }
+ return result;
+ }
+
+
+ private int findFirstObsoleteBlock(long period, int intervalBetweenActivities) {
+ long prevTimestamp = 0;
+ long length = 0;
+
+ int last = myStorage.getLastRecord();
+ while (last != 0) {
+ long t = myStorage.getTimestamp(last);
+ if (prevTimestamp == 0) prevTimestamp = t;
+
+ long delta = prevTimestamp - t;
+ prevTimestamp = t;
+
+ length += delta < intervalBetweenActivities ? delta : 1;
+
+ if (length >= period) return last;
+
+ last = myStorage.getPrevRecord(last);
+ }
+
+ return 0;
+ }
+
+
+ public void flush() {
+ myStorage.flushSome();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2000-2010 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.history.core;
+
+import com.intellij.history.core.changes.ChangeSet;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ChangeSetBlock {
+ private static final int BLOCK_SIZE = 1000;
+ public int id;
+ public final List<ChangeSet> changes;
+
+ public ChangeSetBlock(int id) {
+ this.id = id;
+ this.changes = new ArrayList<ChangeSet>(BLOCK_SIZE);
+ }
+
+ ChangeSetBlock(int id, List<ChangeSet> changes) {
+ this.id = id;
+ this.changes = changes;
+ }
+
+ public void add(ChangeSet changeSet) {
+ changes.add(changeSet);
+ }
+
+ public void removeLast() {
+ changes.remove(changes.size() - 1);
+ }
+
+ public boolean shouldFlush(boolean force) {
+ int count = 0;
+ for (ChangeSet each : changes) {
+ count += each.getChanges().size();
+
+ if (count >= BLOCK_SIZE) return true;
+ if (force && count > 0) return true;
+ }
+ return false;
+ }
+}
package com.intellij.history.core;
-import com.intellij.history.core.changes.Change;
-import com.intellij.history.core.tree.Entry;
+import com.intellij.history.core.changes.ChangeSet;
+import com.intellij.openapi.util.Pair;
import java.util.List;
public abstract class ChangeSetsProcessor {
- protected LocalVcs myVcs;
protected String myPath;
- protected Entry myEntry;
- public ChangeSetsProcessor(LocalVcs vcs, String path) {
- myVcs = vcs;
+ public ChangeSetsProcessor(String path) {
myPath = path;
- myEntry = myVcs.getEntry(path);
}
protected void process() {
- List<Change> changes = collectChanges();
+ Pair<String, List<ChangeSet>> pathAndChanges = collectChanges();
+ List<ChangeSet> changes = pathAndChanges.second;
if (changes.isEmpty()) {
nothingToVisit();
return;
}
- for (Change c : changes) {
- if (c.isLabel()) {
- visitLabel(c);
- }
- else {
- visitRegular(c);
- }
+ for (ChangeSet c : changes) {
+ visit(c);
}
- Change lastChange = changes.get(changes.size() - 1);
- if (!lastChange.isLabel() && !lastChange.isCreationalFor(myEntry)) {
+ ChangeSet lastChange = changes.get(changes.size() - 1);
+ if (!lastChange.isLabelOnly() && !lastChange.isCreationalFor(pathAndChanges.first)) {
visitFirstAvailableNonCreational(lastChange);
}
}
- protected abstract List<Change> collectChanges();
+ protected abstract Pair<String, List<ChangeSet>> collectChanges();
protected abstract void nothingToVisit();
- protected abstract void visitLabel(Change c);
+ protected abstract void visit(ChangeSet changeSet);
- protected abstract void visitRegular(Change c);
-
- protected abstract void visitFirstAvailableNonCreational(Change c);
+ protected abstract void visitFirstAvailableNonCreational(ChangeSet changeSet);
}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.history.core;
-
-import com.intellij.history.core.storage.Content;
-import com.intellij.history.core.storage.Storage;
-import com.intellij.history.core.storage.UnavailableContent;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-
-public abstract class ContentFactory {
- public static final int MAX_CONTENT_LENGTH = 1024 * 1024;
-
- public Content createContent(Storage s) {
- try {
- if (isTooLong()) return new UnavailableContent();
- return s.storeContent(getBytes());
- }
- catch (IOException e) {
- return new UnavailableContent();
- }
- }
-
- private boolean isTooLong() throws IOException {
- return getLength() > MAX_CONTENT_LENGTH;
- }
-
- public boolean equalsTo(Content c) {
- try {
- if (!c.isAvailable()) return false;
- if (isTooLong()) return false;
-
- if (getLength() != c.getBytes().length) return false;
- return Arrays.equals(getBytes(), c.getBytes());
- }
- catch (IOException e) {
- return false;
- }
- }
-
- protected abstract byte[] getBytes() throws IOException;
-
- protected abstract long getLength() throws IOException;
-}
+++ /dev/null
-/*
- * Copyright 2000-2009 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.history.core;
-
-import com.intellij.history.core.storage.Stream;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-public class IdPath {
- private final int[] myParts;
-
- public IdPath(int... parts) {
- myParts = parts;
- }
-
- public IdPath(Stream s) throws IOException {
- myParts = new int[s.readInteger()];
- for (int i = 0; i < myParts.length; i++) {
- myParts[i] = s.readInteger();
- }
- }
-
- public void write(Stream s) throws IOException {
- s.writeInteger(myParts.length);
- // todo try to change with writeArray method
- for (int id : myParts) {
- s.writeInteger(id);
- }
- }
-
- public int getId() {
- return myParts[myParts.length - 1];
- }
-
- public IdPath getParent() {
- if (myParts.length == 1) return null;
- int[] newPath = new int[myParts.length - 1];
- System.arraycopy(myParts, 0, newPath, 0, newPath.length);
- return new IdPath(newPath);
- }
-
- public IdPath appendedWith(int id) {
- // todo use Arrays.copyOf after going to 1.6
- int[] newPath = new int[myParts.length + 1];
- System.arraycopy(myParts, 0, newPath, 0, myParts.length);
- newPath[newPath.length - 1] = id;
- return new IdPath(newPath);
- }
-
- public boolean isChildOrParentOf(IdPath p) {
- return startsWith(p) || p.startsWith(this);
- }
-
- public boolean contains(int id) {
- for (int part : myParts) {
- if (part == id) return true;
- }
- return false;
- }
-
- public boolean startsWith(IdPath p) {
- if (myParts.length < p.myParts.length) return false;
- for (int i = 0; i < p.myParts.length; i++) {
- if (myParts[i] != p.myParts[i]) return false;
- }
- return true;
- }
-
- public boolean rootEquals(int id) {
- return myParts[0] == id;
- }
-
- public IdPath withoutRoot() {
- int[] newPath = new int[myParts.length - 1];
- System.arraycopy(myParts, 1, newPath, 0, newPath.length);
- return new IdPath(newPath);
- }
-
- @Override
- public String toString() {
- String result = "";
- for (int part : myParts) {
- result += part + ".";
- }
- return result.substring(0, result.length() - 1);
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == null || !o.getClass().equals(getClass())) return false;
- return Arrays.equals(myParts, ((IdPath)o).myParts);
- }
-
- @Override
- public int hashCode() {
- throw new UnsupportedOperationException();
- }
-}
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package com.intellij.history.core;
-package com.intellij.history.core.changes;
+import com.intellij.history.ByteContent;
+import com.intellij.history.core.tree.RootEntry;
-class CreateEntryChangeNonAppliedState extends StructuralChangeNonAppliedState {
- public int myId;
+public interface LabelImpl {
+ ByteContent getByteContent(RootEntry root, String path);
}
--- /dev/null
+/*
+ * Copyright 2000-2010 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.history.core;
+
+import com.intellij.openapi.components.impl.stores.StorageUtil;
+import com.intellij.util.io.PagePool;
+import com.intellij.util.io.storage.AbstractRecordsTable;
+
+import java.io.File;
+import java.io.IOException;
+
+public class LinkedRecordsTable extends AbstractRecordsTable {
+ private static final int VERSION = 3;
+
+ private static final int ID_COUNTER_OFFSET = DEFAULT_HEADER_SIZE;
+ private static final int FIRST_RECORD_OFFSET = ID_COUNTER_OFFSET + 8;
+ private static final int LAST_RECORD_OFFSET = FIRST_RECORD_OFFSET + 4;
+ private static final int FS_TIMESTAMP_OFFSET = LAST_RECORD_OFFSET + 4;
+ private static final int HEADER_SIZE = FS_TIMESTAMP_OFFSET + 8;
+
+ private static final int PREV_RECORD_OFFSET = DEFAULT_RECORD_SIZE;
+ private static final int NEXT_RECORD_OFFSET = DEFAULT_RECORD_SIZE + 4;
+ private static final int TIMESTAMP_OFFSET = DEFAULT_RECORD_SIZE + 8;
+
+ private static final int RECORD_SIZE = TIMESTAMP_OFFSET + 8;
+ private static final byte[] ZEROS = new byte[RECORD_SIZE];
+
+ public LinkedRecordsTable(final File storageFilePath, final PagePool pool) throws IOException {
+ super(storageFilePath, pool);
+ }
+
+ @Override
+ protected int getHeaderSize() {
+ return HEADER_SIZE;
+ }
+
+ @Override
+ protected int getRecordSize() {
+ return RECORD_SIZE;
+ }
+
+ @Override
+ protected int getImplVersion() {
+ return VERSION;
+ }
+
+ @Override
+ protected byte[] getZeros() {
+ return ZEROS;
+ }
+
+ public void setFSTimestamp(long timestamp) {
+ markDirty();
+ myStorage.putLong(FS_TIMESTAMP_OFFSET, timestamp);
+ }
+
+ public long getFSTimestamp() {
+ return myStorage.getLong(FS_TIMESTAMP_OFFSET);
+ }
+
+ public void setFirstRecord(int record) {
+ markDirty();
+ myStorage.putInt(FIRST_RECORD_OFFSET, record);
+ }
+
+ public int getFirstRecord() {
+ markDirty();
+ return myStorage.getInt(FIRST_RECORD_OFFSET);
+ }
+
+ public void setLastRecord(int record) {
+ markDirty();
+ myStorage.putInt(LAST_RECORD_OFFSET, record);
+ }
+
+ public int getLastRecord() {
+ markDirty();
+ return myStorage.getInt(LAST_RECORD_OFFSET);
+ }
+
+ public void setPrevRecord(int record, int prevRecord) {
+ markDirty();
+ myStorage.putInt(getOffset(record, PREV_RECORD_OFFSET), prevRecord);
+ }
+
+ public int getPrevRecord(int record) {
+ return myStorage.getInt(getOffset(record, PREV_RECORD_OFFSET));
+ }
+
+ public void setNextRecord(int record, int nextRecord) {
+ markDirty();
+ myStorage.putInt(getOffset(record, NEXT_RECORD_OFFSET), nextRecord);
+ }
+
+ public int getNextRecord(int record) {
+ return myStorage.getInt(getOffset(record, NEXT_RECORD_OFFSET));
+ }
+
+ public void setTimestamp(int record, long timestamp) {
+ markDirty();
+ myStorage.putLong(getOffset(record, TIMESTAMP_OFFSET), timestamp);
+ }
+
+ public long getTimestamp(int record) {
+ return myStorage.getLong(getOffset(record, TIMESTAMP_OFFSET));
+ }
+
+ public long nextId() {
+ markDirty();
+ long result = myStorage.getLong(ID_COUNTER_OFFSET);
+ myStorage.putLong(ID_COUNTER_OFFSET, result + 1);
+ return result;
+ }
+}
+
--- /dev/null
+/*
+ * Copyright 2000-2010 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.history.core;
+
+import com.intellij.history.Clock;
+import com.intellij.util.io.PagePool;
+import com.intellij.util.io.storage.AbstractRecordsTable;
+import com.intellij.util.io.storage.AbstractStorage;
+
+import java.io.File;
+import java.io.IOException;
+
+public class LinkedStorage extends AbstractStorage {
+ public LinkedStorage(String storageFilePath) throws IOException {
+ super(storageFilePath);
+ }
+
+ public LinkedStorage(String storageFilePath, PagePool pool) throws IOException {
+ super(storageFilePath, pool);
+ }
+
+ @Override
+ protected AbstractRecordsTable createRecordsTable(PagePool pool, File recordsFile) throws IOException {
+ return new LinkedRecordsTable(recordsFile, pool);
+ }
+
+ public long getFSTimestamp() {
+ synchronized (myLock) {
+ return ((LinkedRecordsTable)myRecordsTable).getFSTimestamp();
+ }
+ }
+
+ public void setFSTimestamp(long timestamp) {
+ synchronized (myLock) {
+ ((LinkedRecordsTable)myRecordsTable).setFSTimestamp(timestamp);
+ }
+ }
+
+ public long nextId() {
+ synchronized (myLock) {
+ return ((LinkedRecordsTable)myRecordsTable).nextId();
+ }
+ }
+
+ public int getLastRecord() {
+ synchronized (myLock) {
+ return ((LinkedRecordsTable)myRecordsTable).getLastRecord();
+ }
+ }
+
+ public int getPrevRecord(int record) {
+ synchronized (myLock) {
+ return ((LinkedRecordsTable)myRecordsTable).getPrevRecord(record);
+ }
+ }
+
+ public long getTimestamp(int record) {
+ synchronized (myLock) {
+ return ((LinkedRecordsTable)myRecordsTable).getTimestamp(record);
+ }
+ }
+
+ public int createNextRecord() throws IOException {
+ synchronized (myLock) {
+ LinkedRecordsTable table = (LinkedRecordsTable)myRecordsTable;
+ int id = table.createNewRecord();
+ int prev = table.getLastRecord();
+
+ table.setPrevRecord(id, prev);
+ if (prev > 0) {
+ table.setNextRecord(prev, id);
+ }
+ else {
+ table.setFirstRecord(id);
+ }
+ table.setLastRecord(id);
+
+ table.setTimestamp(id, Clock.getCurrentTimestamp());
+
+ return id;
+ }
+ }
+
+ public void deleteRecord(int id) throws IOException {
+ synchronized (myLock) {
+ LinkedRecordsTable table = (LinkedRecordsTable)myRecordsTable;
+
+ int prev = table.getPrevRecord(id);
+ int next = table.getNextRecord(id);
+
+ if (prev == 0) {
+ table.setFirstRecord(next);
+ }
+ else {
+ table.setNextRecord(prev, next);
+ }
+
+ if (next == 0) {
+ table.setLastRecord(prev);
+ }
+ else {
+ table.setPrevRecord(next, prev);
+ }
+
+ table.deleteRecord(id);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2009 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.history.core;
+
+import com.intellij.history.ByteContent;
+import com.intellij.history.core.changes.*;
+import com.intellij.history.core.revisions.RecentChange;
+import com.intellij.history.core.revisions.Revision;
+import com.intellij.history.core.revisions.RevisionAfterChange;
+import com.intellij.history.core.revisions.RevisionBeforeChange;
+import com.intellij.history.core.storage.Content;
+import com.intellij.history.core.tree.Entry;
+import com.intellij.history.core.tree.RootEntry;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LocalHistoryFacade {
+ private final ChangeList myChangeList;
+ private final List<Listener> myListeners = ContainerUtil.createEmptyCOWList();
+
+ public LocalHistoryFacade(ChangeList changeList) {
+ myChangeList = changeList;
+ }
+
+ public void beginChangeSet() {
+ myChangeList.beginChangeSet();
+ }
+
+ public void endChangeSet(String name) {
+ if (myChangeList.endChangeSet(name)) {
+ fireChangeSetFinished();
+ }
+ }
+
+ public void created(String path, boolean isDirectory) {
+ addChange(isDirectory ? new CreateDirectoryChange(myChangeList.nextId(), path)
+ : new CreateFileChange(myChangeList.nextId(), path));
+ }
+
+ public void contentChanged(String path, Content oldContent, long oldTimestamp) {
+ addChange(new ContentChange(myChangeList.nextId(), path, oldContent, oldTimestamp));
+ }
+
+ public void renamed(String path, String oldName) {
+ addChange(new RenameChange(myChangeList.nextId(), path, oldName));
+ }
+
+ public void readOnlyStatusChanged(String path, boolean oldStatus) {
+ addChange(new ROStatusChange(myChangeList.nextId(), path, oldStatus));
+ }
+
+ public void moved(String path, String oldParent) {
+ addChange(new MoveChange(myChangeList.nextId(), path, oldParent));
+ }
+
+ public void deleted(String path, Entry deletedEntry) {
+ addChange(new DeleteChange(myChangeList.nextId(), path, deletedEntry));
+ }
+
+ public LabelImpl putSystemLabel(String name, String projectId, int color) {
+ return putLabel(new PutSystemLabelChange(myChangeList.nextId(), name, projectId, color));
+ }
+