Merge remote branch 'origin/master'

This commit is contained in:
irengrig
2011-10-21 15:36:58 +04:00
305 changed files with 8598 additions and 5325 deletions
+1
View File
@@ -153,6 +153,7 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir
module("jps-builders")
module("jps-model")
}
fileset(dir: "$home/jps/lib", includes: "optimizedFileManager.jar")
fileset(dir: "$home/lib", includesfile: "${home}/lib/required_for_dist.txt")
+2 -2
View File
@@ -222,6 +222,6 @@ libraryLicense(name: "YourKit Java Profiler", libraryName: "yjp-controller-api-r
libraryLicense(name: "protobuf", version: "2.3.0", license: "New BSD", url: "http://code.google.com/p/protobuf/", licenseUrl: "http://code.google.com/p/protobuf/source/browse/trunk/COPYING.txt?r=367")
libraryLicense(name: "Netty", libraryName: "Netty", version: "3.2.5", license: "Apache 2.0", url: "http://www.jboss.org/netty", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
jetbrainsLibrary("JPS")
jetbrainsLibrary("JPS-facade")
jetbrainsLibrary("Maven Embedder")
jetbrainsLibrary("tcServiceMessages")
jetbrainsLibrary("tcServiceMessages")
jetbrainsLibrary("optimizedFileManager.jar")
@@ -58,6 +58,7 @@ import org.jetbrains.jps.server.Server;
import javax.tools.*;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.Future;
import java.util.concurrent.RunnableFuture;
@@ -71,7 +72,7 @@ public class JpsServerManager implements ApplicationComponent{
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.JpsServerManager");
private static final String COMPILE_SERVER_SYSTEM_ROOT = "compile-server";
private volatile OSProcessHandler myProcessHandler;
private final File mySystemDirectory;
private volatile Client myClient = new Client();
private final SequentialTaskExecutor myTaskExecutor = new SequentialTaskExecutor(new SequentialTaskExecutor.AsyncTaskExecutor() {
public void submit(Runnable runnable) {
@@ -80,7 +81,18 @@ public class JpsServerManager implements ApplicationComponent{
});
public JpsServerManager(ProjectManager projectManager) {
final String systemPath = PathManager.getSystemPath();
File system = new File(systemPath);
try {
system = system.getCanonicalFile();
}
catch (IOException e) {
LOG.info(e);
}
mySystemDirectory = system;
projectManager.addProjectManagerListener(new ProjectWatcher());
ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
@Override
public void run() {
@@ -275,12 +287,14 @@ public class JpsServerManager implements ApplicationComponent{
return paths;
}
private static Process launchServer(int port) throws ExecutionException {
private Process launchServer(int port) throws ExecutionException {
final Sdk projectJdk = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk();
final GeneralCommandLine cmdLine = new GeneralCommandLine();
cmdLine.setExePath(((JavaSdkType)projectJdk.getSdkType()).getVMExecutablePath(projectJdk));
cmdLine.addParameter("-ea");
cmdLine.addParameter("-XX:+HeapDumpOnOutOfMemoryError");
cmdLine.addParameter("-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5008");
cmdLine.addParameter("-Xmx256m"); // todo: get this value from settings
cmdLine.addParameter("-Xmx512m"); // todo: get this value from settings
cmdLine.addParameter("-classpath");
final List<File> cp = ClasspathBootstrap.getApplicationClasspath();
@@ -301,8 +315,11 @@ public class JpsServerManager implements ApplicationComponent{
cmdLine.addParameter(org.jetbrains.jps.server.Server.class.getName());
cmdLine.addParameter(Integer.toString(port));
final File workDirectory = new File(PathManager.getSystemPath(), COMPILE_SERVER_SYSTEM_ROOT);
final File workDirectory = new File(mySystemDirectory, COMPILE_SERVER_SYSTEM_ROOT);
workDirectory.mkdirs();
cmdLine.addParameter(FileUtil.toSystemIndependentName(workDirectory.getPath()));
cmdLine.setWorkDirectory(workDirectory);
return cmdLine.createProcess();
@@ -292,7 +292,7 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos
}
console.setActions(consoleActions, ActionPlaces.DEBUGGER_TOOLBAR, myConsole.getPreferredFocusableComponent());
initLogConsoles(myConfiguration, myRunContentDescriptor.getProcessHandler());
initLogConsoles(myConfiguration, myRunContentDescriptor.getProcessHandler(), myConsole);
DefaultActionGroup group = new DefaultActionGroup();
final Executor executor = DefaultDebugExecutor.getDebugExecutorInstance();
@@ -24,12 +24,11 @@ import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Key;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiClassUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.Processor;
import com.intellij.util.containers.Convertor;
import junit.runner.BaseTestRunner;
@@ -53,25 +52,16 @@ public class JUnitUtil {
@NonNls public static final String RUN_WITH = "org.junit.runner.RunWith";
@NonNls public static final String SUITE_METHOD_NAME = "suite";
private static final Key<PsiType> TEST_INTERFACE_KEY = Key.create(TEST_INTERFACE);
public static boolean isSuiteMethod(@NotNull PsiMethod psiMethod, @NotNull Project project) {
public static boolean isSuiteMethod(@NotNull PsiMethod psiMethod) {
if (!psiMethod.hasModifierProperty(PsiModifier.PUBLIC)) return false;
if (!psiMethod.hasModifierProperty(PsiModifier.STATIC)) return false;
if (psiMethod.isConstructor()) return false;
if (psiMethod.getParameterList().getParametersCount() > 0) return false;
final PsiType returnType = psiMethod.getReturnType();
if (returnType == null || returnType instanceof PsiPrimitiveType) return false;
if (!returnType.equalsToText(TEST_INTERFACE) && !returnType.equalsToText(TESTSUITE_CLASS)) {
PsiType cachedTestInterfaceType = project.getUserData(TEST_INTERFACE_KEY);
if (cachedTestInterfaceType == null) {
final PsiType testType = JavaPsiFacade.getInstance(project).getElementFactory().createTypeFromText(TEST_INTERFACE, null);
project.putUserData(TEST_INTERFACE_KEY,testType);
cachedTestInterfaceType = testType;
}
if (!TypeConversionUtil.isAssignable(cachedTestInterfaceType, returnType)) {
return false;
}
}
return psiMethod.getParameterList().getParametersCount() == 0;
return returnType.equalsToText(TEST_INTERFACE)||
returnType.equalsToText(TESTSUITE_CLASS) ||
InheritanceUtil.isInheritor(returnType, TEST_INTERFACE);
}
public static boolean isTestMethod(final Location<? extends PsiMethod> location) {
@@ -123,7 +113,7 @@ public class JUnitUtil {
for (final PsiMethod method : psiClass.getAllMethods()) {
ProgressManager.checkCanceled();
if (isSuiteMethod(method, psiClass.getProject())) return true;
if (isSuiteMethod(method)) return true;
if (isTestAnnotated(method)) return true;
}
@@ -172,6 +162,7 @@ public class JUnitUtil {
return false;
}
@Nullable
private static PsiClass getTestCaseClassOrNull(final Location<?> location) {
final Location<PsiClass> ancestorOrSelf = location.getAncestorOrSelf(PsiClass.class);
final PsiClass aClass = ancestorOrSelf.getPsiElement();
@@ -197,6 +188,8 @@ public class JUnitUtil {
if (testCaseClass == null) throw new NoJUnitException(scope.getDisplayName());
return testCaseClass;
}
@Nullable
private static PsiClass getTestCaseClassOrNull(final GlobalSearchScope scope, final Project project) {
return JavaPsiFacade.getInstance(project).findClass(TESTCASE_CLASS, scope);
}
@@ -246,7 +239,7 @@ public class JUnitUtil {
public static PsiMethod findFirstTestMethod(PsiClass clazz) {
PsiMethod testMethod = null;
for (PsiMethod method : clazz.getMethods()) {
if (isTestMethod(MethodLocation.elementInClass(method, clazz)) || isSuiteMethod(method, clazz.getProject())) {
if (isTestMethod(MethodLocation.elementInClass(method, clazz)) || isSuiteMethod(method)) {
testMethod = method;
break;
}
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.openapi.util.Key;
import com.intellij.psi.*;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NonNls;
@@ -28,6 +29,8 @@ import static com.intellij.psi.CommonClassNames.*;
* @author peter
*/
class CollectionsUtilityMethodsProvider {
public static final Key<Boolean> COLLECTION_FACTORY = Key.create("CollectionFactory");
public static void addCompletions(@NotNull final JavaSmartCompletionParameters parameters,
@NotNull final Consumer<LookupElement> result) {
final PsiElement element = parameters.getPosition();
@@ -85,6 +88,7 @@ class CollectionsUtilityMethodsProvider {
final JavaMethodCallElement item = new JavaMethodCallElement(method, false, false);
item.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
item.setInferenceSubstitutor(SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(method, expectedType));
item.putUserData(COLLECTION_FACTORY, true);
result.consume(item);
}
@@ -542,7 +542,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{
!(position.getParent() instanceof PsiLiteralExpression) &&
!(position.getParent().getParent() instanceof PsiSwitchLabelStatement)) {
for (final ExpectedTypeInfo info : JavaSmartCompletionContributor.getExpectedTypes(parameters)) {
new JavaMembersGetter(info.getDefaultType()).addMembers(position, parameters.getInvocationCount() > 0, new Consumer<LookupElement>() {
new JavaMembersGetter(info.getDefaultType()).addMembers(position, parameters.getInvocationCount() > 1, new Consumer<LookupElement>() {
@Override
public void consume(LookupElement element) {
result.addElement(element);
@@ -223,9 +223,10 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
parent != null &&
!(parent.getParent() instanceof PsiSwitchLabelStatement)) {
for (ExpectedTypeInfo info : mergedInfos) {
new JavaMembersGetter(info.getType()).addMembers(position, true, noTypeCheck);
final boolean searchInheritors = params.getInvocationCount() > 1;
new JavaMembersGetter(info.getType()).addMembers(position, searchInheritors, noTypeCheck);
if (!info.getDefaultType().equals(info.getType())) {
new JavaMembersGetter(info.getDefaultType()).addMembers(position, true, noTypeCheck);
new JavaMembersGetter(info.getDefaultType()).addMembers(position, searchInheritors, noTypeCheck);
}
}
}
@@ -388,7 +389,8 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
if (parameterList == null) return null;
PsiElement parent = parameterList.getParent();
assert parent instanceof PsiJavaCodeReferenceElement : parent + "; text=" + parent.getText();
if (!(parent instanceof PsiJavaCodeReferenceElement)) return null;
final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)parent;
final int parameterIndex;
@@ -44,6 +44,7 @@ public class PreferLocalVariablesLiteralsAndAnnoMethodsWeigher extends LookupEle
qualifiedWithField,
qualifiedWithGetter,
superMethodParameters,
collectionFactory,
normal,
nonInitialized,
classLiteral,
@@ -70,6 +71,10 @@ public class PreferLocalVariablesLiteralsAndAnnoMethodsWeigher extends LookupEle
if (object instanceof String && item.getUserData(JavaCompletionUtil.SUPER_METHOD_PARAMETERS) == Boolean.TRUE) {
return MyResult.superMethodParameters;
}
if (item.getUserData(CollectionsUtilityMethodsProvider.COLLECTION_FACTORY) != null) {
return MyResult.collectionFactory;
}
final JavaChainLookupElement chain = item.as(JavaChainLookupElement.CLASS_CONDITION_KEY);
if (chain != null) {
@@ -120,7 +120,8 @@ public class AnnotationParameterInfoHandler implements ParameterInfoHandler<PsiA
private static PsiAnnotationMethod findAnnotationMethod(PsiFile file, int offset) {
PsiNameValuePair pair = ParameterInfoUtils.findParentOfType(file, offset, PsiNameValuePair.class);
if (pair == null) return null;
final PsiElement resolved = pair.getReference().resolve();
final PsiReference reference = pair.getReference();
final PsiElement resolved = reference != null ? reference.resolve():null;
return resolved instanceof PsiAnnotationMethod ? (PsiAnnotationMethod)resolved : null;
}
}
@@ -38,9 +38,7 @@ import com.intellij.codeInspection.ui.EntryPointsNode;
import com.intellij.codeInspection.ui.InspectionNode;
import com.intellij.codeInspection.ui.InspectionTreeNode;
import com.intellij.codeInspection.util.RefFilter;
import com.intellij.ide.DataManager;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
@@ -49,7 +47,6 @@ import com.intellij.openapi.extensions.ExtensionPoint;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.*;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiClassImplUtil;
@@ -203,15 +200,7 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool {
gc.gridy++;
add(myNonJavaCheckbox, gc);
final JButton configureAnnotations = new JButton("Configure annotations");
configureAnnotations.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(OptionsPanel.this));
if (project == null) project = ProjectManager.getInstance().getDefaultProject();
EntryPointsManagerImpl.getInstance(project).configureAnnotations();
}
});
final JButton configureAnnotations = EntryPointsManagerImpl.createConfigureAnnotationsBtn(this);
gc.fill = GridBagConstraints.NONE;
gc.gridy++;
@@ -446,8 +435,7 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool {
if (RefUtil.isImplicitUsage(element)) return true;
if (element instanceof PsiModifierListOwner) {
final EntryPointsManagerImpl entryPointsManager = EntryPointsManagerImpl.getInstance(element.getProject());
if (AnnotationUtil.isAnnotated((PsiModifierListOwner)element, entryPointsManager.ADDITIONAL_ANNOTATIONS) ||
AnnotationUtil.isAnnotated((PsiModifierListOwner)element, entryPointsManager.getAdditionalAnnotations())) {
if (entryPointsManager.isEntryPoint((PsiModifierListOwner)element)) {
return true;
}
}
@@ -25,8 +25,11 @@
package com.intellij.codeInspection.ex;
import com.intellij.ExtensionPoints;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInspection.reference.*;
import com.intellij.codeInspection.util.SpecialAnnotationsUtil;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.ServiceManager;
@@ -37,10 +40,12 @@ import com.intellij.openapi.extensions.ExtensionPointListener;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.extensions.PluginDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.*;
import com.intellij.profile.codeInspection.InspectionProfileManager;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiModifierListOwner;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import org.jdom.Element;
@@ -49,6 +54,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
@State(
@@ -360,6 +367,19 @@ public class EntryPointsManagerImpl implements PersistentStateComponent<Element>
}.show();
}
public static JButton createConfigureAnnotationsBtn(final JComponent parent) {
final JButton configureAnnotations = new JButton("Configure annotations...");
configureAnnotations.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(parent));
if (project == null) project = ProjectManager.getInstance().getDefaultProject();
EntryPointsManagerImpl.getInstance(project).configureAnnotations();
}
});
return configureAnnotations;
}
public void addAllPersistentEntries(EntryPointsManagerImpl manager) {
myPersistentEntryPoints.putAll(manager.myPersistentEntryPoints);
}
@@ -411,4 +431,9 @@ public class EntryPointsManagerImpl implements PersistentStateComponent<Element>
public void setAddNonJavaEntries(final boolean addNonJavaEntries) {
myAddNonJavaEntries = addNonJavaEntries;
}
public boolean isEntryPoint(PsiModifierListOwner element) {
return AnnotationUtil.isAnnotated(element, ADDITIONAL_ANNOTATIONS) ||
AnnotationUtil.isAnnotated(element, getAdditionalAnnotations());
}
}
@@ -28,6 +28,7 @@ import com.intellij.analysis.AnalysisScope;
import com.intellij.codeInsight.CodeInsightUtilBase;
import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.ex.EntryPointsManagerImpl;
import com.intellij.codeInspection.reference.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
@@ -45,6 +46,8 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -71,6 +74,7 @@ public class UnusedParametersInspection extends GlobalJavaInspectionTool {
if ((refMethod.isAbstract() || refMethod.getOwnerClass().isInterface()) && refMethod.getDerivedMethods().isEmpty()) return null;
if (RefUtil.isEntryPoint(refMethod)) return null;
if (EntryPointsManagerImpl.getInstance(manager.getProject()).isEntryPoint(refMethod.getElement())) return null;
if (refMethod.isAppMain()) return null;
@@ -215,6 +219,18 @@ public class UnusedParametersInspection extends GlobalJavaInspectionTool {
return SHORT_NAME;
}
@Override
public JComponent createOptionsPanel() {
final JPanel panel = new JPanel(new GridBagLayout());
final GridBagConstraints gc =
new GridBagConstraints(GridBagConstraints.RELATIVE, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
new Insets(5, 0, 0, 0), 0, 0);
panel.add(EntryPointsManagerImpl.createConfigureAnnotationsBtn(panel), gc);
gc.weightx = 1;
gc.fill = GridBagConstraints.HORIZONTAL;
panel.add(Box.createHorizontalBox(), gc);
return panel;
}
private static class AcceptSuggested implements LocalQuickFix {
private final RefManager myManager;
@@ -46,7 +46,7 @@
<text resource-bundle="messages/InspectionsBundle" key="inspection.unused.symbol.public.method.parameters"/>
</properties>
</component>
<grid id="a47a5" binding="myAnnos" layout-manager="BorderLayout" hgap="0" vgap="0">
<grid id="a47a5" binding="myAnnos" layout-manager="GridBagLayout">
<constraints>
<grid row="4" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
@@ -16,7 +16,6 @@
package com.intellij.codeInspection.unusedSymbol;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
@@ -25,10 +24,7 @@ import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
import com.intellij.codeInspection.ex.EntryPointsManagerImpl;
import com.intellij.codeInspection.ex.UnfairLocalInspectionTool;
import com.intellij.codeInspection.util.SpecialAnnotationsUtil;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.psi.PsiModifierListOwner;
import org.intellij.lang.annotations.Pattern;
import org.jetbrains.annotations.NonNls;
@@ -128,17 +124,13 @@ public class UnusedSymbolLocalInspection extends BaseJavaLocalInspectionTool imp
myCheckClassesCheckBox.addActionListener(listener);
myCheckParametersCheckBox.addActionListener(listener);
myReportUnusedParametersInPublics.addActionListener(listener);
final JButton configureAnnotations = new JButton("Configure annotations");
configureAnnotations.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(myPanel));
if (project == null) project = ProjectManager.getInstance().getDefaultProject();
EntryPointsManagerImpl.getInstance(project).configureAnnotations();
}
});
myAnnos.add(configureAnnotations, BorderLayout.NORTH);
final GridBagConstraints gc =
new GridBagConstraints(GridBagConstraints.RELATIVE, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
new Insets(0, 0, 0, 0), 0, 0);
myAnnos.add(EntryPointsManagerImpl.createConfigureAnnotationsBtn(myPanel), gc);
gc.weightx = 1;
gc.fill = GridBagConstraints.HORIZONTAL;
myAnnos.add(Box.createHorizontalBox(), gc);
}
public JComponent getPanel() {
@@ -160,8 +152,6 @@ public class UnusedSymbolLocalInspection extends BaseJavaLocalInspectionTool imp
}
public static boolean isInjected(final PsiModifierListOwner modifierListOwner) {
final EntryPointsManagerImpl entryPointsManager = EntryPointsManagerImpl.getInstance(modifierListOwner.getProject());
return AnnotationUtil.isAnnotated(modifierListOwner, entryPointsManager.ADDITIONAL_ANNOTATIONS) ||
AnnotationUtil.isAnnotated(modifierListOwner, entryPointsManager.getAdditionalAnnotations());
return EntryPointsManagerImpl.getInstance(modifierListOwner.getProject()).isEntryPoint(modifierListOwner);
}
}
@@ -95,7 +95,7 @@ public class ClassTreeNode extends BasePsiMemberNode<PsiClass>{
@Override
public String getTitle() {
final PsiClass psiClass = getValue();
if (psiClass != null) {
if (psiClass != null && psiClass.isValid()) {
return psiClass.getQualifiedName();
}
return super.getTitle();
@@ -19,10 +19,7 @@ import com.intellij.ide.structureView.impl.common.PsiTreeElementBase;
import com.intellij.navigation.ColoredItemPresentation;
import com.intellij.openapi.editor.colors.CodeInsightColors;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.psi.PsiDocCommentOwner;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiModifierListOwner;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
public abstract class JavaClassTreeElementBase<Value extends PsiElement> extends PsiTreeElementBase<Value> implements AccessLevelProvider,
@@ -44,7 +41,11 @@ public abstract class JavaClassTreeElementBase<Value extends PsiElement> extends
}
public int getAccessLevel() {
return PsiUtil.getAccessLevel(((PsiModifierListOwner)getElement()).getModifierList());
final PsiModifierList modifierList = ((PsiModifierListOwner)getElement()).getModifierList();
if (modifierList == null) {
return PsiUtil.ACCESS_LEVEL_PUBLIC;
}
return PsiUtil.getAccessLevel(modifierList);
}
public int getSubLevel() {
@@ -62,8 +62,7 @@ public class JavaDirectoryServiceImpl extends JavaDirectoryService {
List<PsiClass> classes = null;
for (PsiFile file : dir.getFiles()) {
FileViewProvider viewProvider = file.getViewProvider();
if (file instanceof PsiClassOwner && file == viewProvider.getPsi(viewProvider.getBaseLanguage())) {
if (file instanceof PsiClassOwner && file.getViewProvider().getLanguages().size() == 1) {
PsiClass[] psiClasses = ((PsiClassOwner)file).getClasses();
if (psiClasses.length == 0) continue;
if (classes == null) classes = new ArrayList<PsiClass>();
@@ -33,7 +33,7 @@ public class PsiJavaDirectoryFactory extends PsiDirectoryFactory {
myManager = manager;
}
public PsiDirectory createDirectory(final VirtualFile file) {
public PsiDirectory createDirectory(@NotNull final VirtualFile file) {
return new PsiJavaDirectoryImpl(myManager, file);
}
@@ -59,9 +59,7 @@ import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -243,10 +241,28 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet
return len;
}
private int getTypesColumnWidth() {
private int getNamesMaxLength() {
int len = 0;
for (ParameterTableModelItemBase<ParameterInfoImpl> item : myParametersTableModel.getItems()) {
final String text = item.parameter.getName();
len = Math.max(len, text == null ? 0 : text.length());
}
return len;
}
private int getColumnWidth(int index) {
int letters = getTypesMaxLength() + (index == 0 ? 1 : getNamesMaxLength() + 2);
Font font = EditorColorsManager.getInstance().getGlobalScheme().getFont(EditorFontType.PLAIN);
font = new Font(font.getFontName(), font.getStyle(), 12);
return (getTypesMaxLength() + 1)* Toolkit.getDefaultToolkit().getFontMetrics(font).stringWidth("W");
return letters * Toolkit.getDefaultToolkit().getFontMetrics(font).stringWidth("W");
}
private int getTypesColumnWidth() {
return getColumnWidth(0);
}
private int getNamesColumnWidth() {
return getColumnWidth(1);
}
@Override
@@ -351,7 +367,12 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet
if (me == null) {
return myTypeEditor.getFocusTarget();
}
return me.getPoint().getX() <= getTypesColumnWidth() ? myTypeEditor.getFocusTarget() : myNameEditor.getFocusTarget();
final double x = me.getPoint().getX();
return x <= getTypesColumnWidth()
? myTypeEditor.getFocusTarget()
: myDefaultValueEditor == null || x <= getNamesColumnWidth()
? myNameEditor.getFocusTarget()
: myDefaultValueEditor.getFocusTarget();
}
@Override
@@ -93,7 +93,7 @@ public class IntroduceConstantHandler extends BaseExpressionToFieldHandler {
protected Settings showRefactoringDialog(Project project,
Editor editor,
final Editor editor,
PsiClass parentClass,
PsiExpression expr,
PsiType type,
@@ -150,31 +150,32 @@ public class IntroduceConstantHandler extends BaseExpressionToFieldHandler {
String enteredName = null;
boolean replaceAllOccurrences = true;
final TypeSelectorManagerImpl typeSelectorManager = new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurrences);
if (editor != null && editor.getSettings().isVariableInplaceRenameEnabled() && (expr == null || expr.isPhysical())) {
final AbstractInplaceIntroducer activeIntroducer = AbstractInplaceIntroducer.getActiveIntroducer(editor);
if (activeIntroducer == null) {
myInplaceIntroduceConstantPopup =
new InplaceIntroduceConstantPopup(project, editor, parentClass, expr, localVariable, occurrences, typeSelectorManager,
new InplaceIntroduceConstantPopup(project, editor, parentClass, expr, localVariable, occurrences,
new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurrences),
anchorElement, anchorElementIfAll,
expr != null ? createOccurrenceManager(expr, parentClass) : null);
if (myInplaceIntroduceConstantPopup.startInplaceIntroduceTemplate() ){
return null;
}
} else {
AbstractInplaceIntroducer.stopIntroduce(editor);
activeIntroducer.stopIntroduce(editor);
expr = (PsiExpression)activeIntroducer.getExpr();
localVariable = (PsiLocalVariable)activeIntroducer.getLocalVariable();
occurrences = (PsiExpression[])activeIntroducer.getOccurrences();
enteredName = activeIntroducer.getInputName();
replaceAllOccurrences = activeIntroducer.isReplaceAllOccurrences();
type = ((InplaceIntroduceConstantPopup)activeIntroducer).getType();
}
}
final IntroduceConstantDialog dialog =
new IntroduceConstantDialog(project, parentClass, expr, localVariable, localVariable != null, occurrences, getParentClass(),
typeSelectorManager, enteredName);
new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurrences), enteredName);
dialog.setReplaceAllOccurrences(replaceAllOccurrences);
dialog.show();
if (!dialog.isOK()) {
@@ -25,6 +25,7 @@ import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.introduce.inplace.AbstractInplaceIntroducer;
import com.intellij.refactoring.introduceParameter.AbstractJavaInplaceIntroducer;
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.refactoring.util.occurrences.*;
@@ -102,7 +103,6 @@ public class IntroduceFieldHandler extends BaseExpressionToFieldHandler {
final boolean currentMethodConstructor = containingMethod != null && containingMethod.isConstructor();
final boolean allowInitInMethod = (!currentMethodConstructor || !isInSuperOrThis) && (anchorElement instanceof PsiLocalVariable || anchorElement instanceof PsiStatement);
final boolean allowInitInMethodIfAll = (!currentMethodConstructor || !isInSuperOrThis) && anchorElementIfAll instanceof PsiStatement;
final TypeSelectorManagerImpl typeSelectorManager = new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurrences);
String enteredName = null;
boolean replaceAll = false;
@@ -110,20 +110,21 @@ public class IntroduceFieldHandler extends BaseExpressionToFieldHandler {
final AbstractInplaceIntroducer activeIntroducer = AbstractInplaceIntroducer.getActiveIntroducer(editor);
if (activeIntroducer == null) {
myInplaceIntroduceFieldPopup =
new InplaceIntroduceFieldPopup(localVariable, parentClass, declareStatic, currentMethodConstructor, occurrences, expr, typeSelectorManager, editor,
allowInitInMethod, allowInitInMethodIfAll, anchorElement, anchorElementIfAll, expr != null ? createOccurrenceManager(
expr, parentClass) : null,
project);
new InplaceIntroduceFieldPopup(localVariable, parentClass, declareStatic, currentMethodConstructor, occurrences, expr,
new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurrences), editor,
allowInitInMethod, allowInitInMethodIfAll, anchorElement, anchorElementIfAll,
expr != null ? createOccurrenceManager(expr, parentClass) : null,project);
if (myInplaceIntroduceFieldPopup.startInplaceIntroduceTemplate()) {
return null;
}
} else {
AbstractInplaceIntroducer.stopIntroduce(editor);
activeIntroducer.stopIntroduce(editor);
expr = (PsiExpression)activeIntroducer.getExpr();
localVariable = (PsiLocalVariable)activeIntroducer.getLocalVariable();
occurrences = (PsiExpression[])activeIntroducer.getOccurrences();
enteredName = activeIntroducer.getInputName();
replaceAll = activeIntroducer.isReplaceAllOccurrences();
type = ((AbstractJavaInplaceIntroducer)activeIntroducer).getType();
IntroduceFieldDialog.ourLastInitializerPlace = ((InplaceIntroduceFieldPopup)activeIntroducer).getInitializerPlace();
}
}
@@ -133,7 +134,7 @@ public class IntroduceFieldHandler extends BaseExpressionToFieldHandler {
currentMethodConstructor,
localVariable != null, declareStatic, occurrences,
allowInitInMethod, allowInitInMethodIfAll,
typeSelectorManager,
new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurrences),
enteredName
);
dialog.setReplaceAllOccurrences(replaceAll);
@@ -96,7 +96,7 @@ public abstract class AbstractJavaInplaceIntroducer extends AbstractInplaceIntro
TypeSelectorManagerImpl.typeSelected(psiVariable.getType(), getType());//myDefaultType.getType());
}
protected PsiType getType() {
public PsiType getType() {
return myTypeSelectorManager.getDefaultType();
}
@@ -400,11 +400,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R
final String propName = myLocalVar != null ? JavaCodeStyleManager
.getInstance(myProject).variableNameToPropertyName(myLocalVar.getName(), VariableKind.LOCAL_VARIABLE) : null;
final PsiType initializerType = IntroduceParameterProcessor.getInitializerType(null, myExpr, myLocalVar);
TypeSelectorManagerImpl typeSelectorManager = myExpr != null
? new TypeSelectorManagerImpl(myProject, initializerType, myExpr, occurences)
: new TypeSelectorManagerImpl(myProject, initializerType, occurences);
PsiType initializerType = IntroduceParameterProcessor.getInitializerType(null, myExpr, myLocalVar);
boolean isInplaceAvailableOnDataContext = myEditor != null && myEditor.getSettings().isVariableInplaceRenameEnabled();
@@ -421,7 +417,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R
myInplaceIntroduceParameterPopup =
new InplaceIntroduceParameterPopup(myProject, myEditor, classMemberRefs,
typeSelectorManager,
createTypeSelectorManager(occurences, initializerType),
myExpr, myLocalVar, method, methodToSearchFor, occurences,
getParamsToRemove(method, occurences),
mustBeFinal);
@@ -430,13 +426,14 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R
}
}
else {
AbstractInplaceIntroducer.stopIntroduce(myEditor);
activeIntroducer.stopIntroduce(myEditor);
myExpr = (PsiExpression)activeIntroducer.getExpr();
myLocalVar = (PsiLocalVariable)activeIntroducer.getLocalVariable();
occurences = (PsiExpression[])activeIntroducer.getOccurrences();
enteredName = activeIntroducer.getInputName();
replaceAllOccurrences = activeIntroducer.isReplaceAllOccurrences();
delegate = ((InplaceIntroduceParameterPopup)activeIntroducer).isGenerateDelegate();
initializerType = ((AbstractJavaInplaceIntroducer)activeIntroducer).getType();
}
}
if (ApplicationManager.getApplication().isUnitTestMode()) {
@@ -455,7 +452,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R
final IntroduceParameterDialog dialog =
new IntroduceParameterDialog(myProject, classMemberRefs, occurences, myLocalVar, myExpr,
createNameSuggestionGenerator(myExpr, propName, myProject, enteredName),
typeSelectorManager, methodToSearchFor, method, getParamsToRemove(method, occurences), mustBeFinal);
createTypeSelectorManager(occurences, initializerType), methodToSearchFor, method, getParamsToRemove(method, occurences), mustBeFinal);
dialog.setReplaceAllOccurrences(replaceAllOccurrences);
dialog.setGenerateDelegate(delegate);
dialog.show();
@@ -465,6 +462,11 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R
}
}
private TypeSelectorManagerImpl createTypeSelectorManager(PsiExpression[] occurences, PsiType initializerType) {
return myExpr != null ? new TypeSelectorManagerImpl(myProject, initializerType, myExpr, occurences)
: new TypeSelectorManagerImpl(myProject, initializerType, occurences);
}
private TIntArrayList getParamsToRemove(PsiMethod method, PsiExpression[] occurences) {
PsiExpression expressionToRemoveParamFrom = myExpr;
if (myExpr == null) {
@@ -33,12 +33,14 @@ public class PackageNameReferenceEditorCombo extends ReferenceEditorComboWithBro
super(null, text, project, false, recentsKey);
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
PackageChooserDialog chooser = new PackageChooserDialog(chooserTitle, project);
final PackageChooserDialog chooser = new PackageChooserDialog(chooserTitle, project);
chooser.selectPackage(getText());
chooser.show();
PsiPackage aPackage = chooser.getSelectedPackage();
if (aPackage != null) {
setText(aPackage.getQualifiedName());
if (chooser.isOK()) {
final PsiPackage aPackage = chooser.getSelectedPackage();
if (aPackage != null) {
setText(aPackage.getQualifiedName());
}
}
}
});
@@ -33,7 +33,6 @@ import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.IFileElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.util.PsiUtilCore;
import org.jetbrains.annotations.NotNull;
/**
@@ -82,7 +81,7 @@ public class JavaParserDefinition implements ParserDefinition {
return ((JavaStubElementType)type).createPsi(node);
}
return PsiUtilCore.NULL_PSI_ELEMENT;
throw new IllegalStateException("incorrect element type for JavaParserDefinition: " + type);
}
public PsiFile createFile(final FileViewProvider viewProvider) {
@@ -306,8 +306,7 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
Set<String> names = null;
for (PsiDirectory dir : psiPackage.getDirectories(scope)) {
for (PsiFile file : dir.getFiles()) {
FileViewProvider viewProvider = file.getViewProvider();
if (file instanceof PsiClassOwner && file == viewProvider.getPsi(viewProvider.getBaseLanguage())) {
if (file instanceof PsiClassOwner && file.getViewProvider().getLanguages().size() == 1) {
Set<String> inFile = file instanceof PsiClassOwnerEx ? ((PsiClassOwnerEx)file).getClassNames() : getClassNames(((PsiClassOwner)file).getClasses());
if (inFile.isEmpty()) continue;
@@ -2,7 +2,7 @@ public class Foo {
{
for(int i = 0; i < 100; i++) {
x = 3;
<caret>
}
<caret>
}
}
@@ -1,7 +1,7 @@
public class Foo {
{
<caret>
for (int i = 0; i < 100; i++) {
<caret>
}
}
}
@@ -1,6 +1,6 @@
public class Foo {
{
<caret>
x = 3;
<caret>
}
}
@@ -1,7 +1,7 @@
public class Test {
{
x = 2;
<caret>
foo();
<caret>
}
}
@@ -0,0 +1,8 @@
public class Aaaaaaa {
{
java.util.List<String> local = null;
java.util.List<String> l = <caret>
}
}
@@ -48,7 +48,7 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase {
configure();
assertStringItems("foos().toArray(EMPTY_ARRAY)", "foos().toArray(EMPTY_ARRAY2)");
selectItem(myItems[0]);
checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java");
checkResult();
}
public void testToArrayGenericArrayCreation() throws Throwable { doTest(); }
@@ -62,7 +62,7 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase {
configure();
assertStringItems("foos().toArray(Bar.EMPTY_ARRAY)", "foos().toArray(Bar.EMPTY_ARRAY2)");
selectItem(myItems[0]);
checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java");
checkResult();
}
public void testNonInitializedField() throws Throwable { doTest(); }
@@ -104,14 +104,14 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase {
assertEquals("Arrays.asList(f.bar())", ((LookupItem)((LookupElementDecorator)myItems[0]).getDelegate()).getPresentableText());
assertEquals("Arrays.asList(f.foo())", ((LookupItem)((LookupElementDecorator)myItems[1]).getDelegate()).getPresentableText());
selectItem(myItems[1]);
checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java");
checkResult();
}
public void testRestoreInitialPrefix() throws Throwable {
configureByFileNoComplete(BASE_PATH + "/" + getTestName(false) + ".java");
complete(1);
assertStringItems("MyEnum.Bar", "MyEnum.Foo");
checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java");
checkResult();
complete(1);
assertStringItems("my.getEnum", "MyEnum.Bar", "MyEnum.Foo");
}
@@ -155,13 +155,17 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase {
public void testEmptyListInMethodCall() throws Throwable {
configure();
selectItem(myItems[0]);
checkResult();
}
private void checkResult() {
checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java");
}
public void testSingletonMap() throws Throwable {
configure();
selectItem(myItems[0]);
checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java");
checkResult();
}
protected void checkResultByFile(@NonNls final String filePath) {
@@ -174,7 +178,19 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase {
private void doTest() throws Exception {
configure();
checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java");
checkResult();
}
public void testInheritorMembers() throws Throwable {
configure();
selectItem(myItems[0]);
checkResult();
}
public void testInheritorEnumMembers() throws Throwable {
configure();
selectItem(myItems[0]);
checkResult();
}
@Override
@@ -21,7 +21,7 @@ public class SmartTypeCompletionOrderingTest extends CompletionSortingTestCase {
}
public void testJComponentAdd() throws Throwable {
checkPreferredItems(0, "name", "b", "foo", "fooBean239", "this");
checkPreferredItems(0, "name", "b", "fooBean239", "this", "getName");
}
public void testJComponentAddNew() throws Throwable {
@@ -287,7 +287,14 @@ public class SmartTypeCompletionOrderingTest extends CompletionSortingTestCase {
checkPreferredItems(0, "boo", "bar")
}
public void testPreferCollectionsEmptyList() throws Throwable {
myFixture.addClass("package foo; public class FList<T> implements java.util.List<T> { public static <T> FList<T> emptyList() {} }");
configureNoCompletion(getTestName(false) + ".java");
myFixture.complete(CompletionType.SMART, 2);
assertPreferredItems(0, "local", "local.subList", "emptyList", "singletonList", "unmodifiableList");
assert 'Collections.emptyList' in lookup.items[2].allLookupStrings
assert 'FList.emptyList' in lookup.items[5].allLookupStrings
}
@Override
protected String getBasePath() {
@@ -1026,8 +1026,6 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
}
public void testArrayInitializerBeforeVarargs() throws Throwable { doTest(); }
public void testInheritorMembers() throws Throwable { doTest(); }
public void testInheritorEnumMembers() throws Throwable { doTest(); }
public void testDuplicateMembersFromSuperClass() throws Throwable { doTest(); }
public void testMemberImportStatically() {
@@ -249,6 +249,11 @@ public class LocalFileSystemTest extends IdeaTestCase{
VirtualFile file = LocalFileSystem.getInstance().findFileByPath("wrong_path");
assertNull(file);
if (SystemInfo.isWindows) {
assertNotNull(LocalFileSystem.getInstance().findFileByPath("\\\\unit-133"));
assertNotNull(LocalFileSystem.getInstance().findFileByIoFile(new File("\\\\unit-133")));
}
if (SystemInfo.isWindows && new File("c:").exists()) {
VirtualFile root = LocalFileSystem.getInstance().findFileByPath("c:");
assertNotNull(root);
+9
View File
@@ -18,6 +18,15 @@
<orderEntry type="library" name="jgoodies-forms" level="project" />
<orderEntry type="library" name="Netty" level="project" />
<orderEntry type="library" exported="" name="protobuf" level="project" />
<orderEntry type="module-library" scope="RUNTIME">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../lib/optimizedFileManager.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>
@@ -20,6 +20,8 @@ public abstract class Builder {
OK, ABORT, ADDITIONAL_PASS_REQUIRED
}
public abstract String getName();
public abstract ExitCode build(CompileContext context, ModuleChunk chunk) throws ProjectBuildException;
public abstract String getDescription();
@@ -3,9 +3,8 @@ package org.jetbrains.jps.incremental;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.util.containers.SLRUCache;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.Module;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.Project;
import org.jetbrains.ether.dependencyView.Mappings;
import org.jetbrains.jps.*;
import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.storage.BuildDataManager;
@@ -22,9 +21,13 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
private final CompileScope myScope;
private final boolean myIsMake;
private final ProjectChunks myProductionChunks;
private final ProjectChunks myTestChunks;
private final MessageHandler myDelegateMessageHandler;
private volatile boolean myCompilingTests = false;
private final BuildDataManager myDataManager;
private final Mappings myMappings;
private final Set<Module> myDirtyModules = new HashSet<Module>();
private SLRUCache<Module, FSSnapshot> myFilesCache = new SLRUCache<Module, FSSnapshot>(10, 10) {
@NotNull
@@ -32,23 +35,86 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
return buildSnapshot(key);
}
};
private final ProjectPaths myProjectPaths;
public CompileContext(CompileScope scope, String projectName, boolean isMake, MessageHandler delegateMessageHandler) {
public CompileContext(CompileScope scope,
String projectName,
boolean isMake,
final Mappings mappings,
ProjectChunks productionChunks,
ProjectChunks testChunks,
MessageHandler delegateMessageHandler) {
myScope = scope;
myIsMake = isMake;
myProductionChunks = productionChunks;
myTestChunks = testChunks;
myDelegateMessageHandler = delegateMessageHandler;
final File buildDataRoot = new File(System.getProperty("user.home"), ".jps" + File.separator + projectName + File.separator + "build_data");
myDataManager = new BuildDataManager(buildDataRoot);
myDataManager = new BuildDataManager(projectName);
myMappings = mappings;
myProjectPaths = new ProjectPaths(scope.getProject());
}
public Project getProject() {
return myScope.getProject();
}
public ProjectPaths getProjectPaths() {
return myProjectPaths;
}
public boolean isMake() {
return myIsMake;
}
public boolean isDirty(ModuleChunk chunk) {
for (Module module : chunk.getModules()) {
if (isDirty(module)) {
return true;
}
}
return false;
}
public boolean isDirty(Module module) {
return myDirtyModules.contains(module);
}
public void setDirty(ModuleChunk chunk, boolean isDirty) {
final Set<Module> modules = chunk.getModules();
if (isDirty) {
myDirtyModules.addAll(modules);
}
else {
myDirtyModules.removeAll(modules);
}
// now mark all modules that depend on dirty modules
final ClasspathKind classpathKind = ClasspathKind.compile(isCompilingTests());
final ProjectChunks chunks = isCompilingTests()? myTestChunks : myProductionChunks;
boolean found = false;
for (ModuleChunk moduleChunk : chunks.getChunkList()) {
if (!found) {
if (moduleChunk.equals(chunk)) {
found = true;
}
}
else {
MODULES_LOOP: for (final Module module : moduleChunk.getModules()) {
for (ClasspathItem dependency : module.getClasspath(classpathKind)) {
if (dependency instanceof Module && isDirty((Module)dependency)) {
myDirtyModules.addAll(moduleChunk.getModules());
break MODULES_LOOP;
}
}
}
}
}
}
public Mappings getMappings() {
return myMappings;
}
public boolean isCompilingTests() {
return myCompilingTests;
}
@@ -84,22 +150,6 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
}
/** @noinspection unchecked*/
//private boolean processModule(Module module, FileProcessor processor) throws Exception {
// final Set<File> excludes = new HashSet<File>();
// for (String excludePath : (Collection<String>)module.getExcludes()) {
// excludes.add(new File(excludePath));
// }
//
// final Collection<String> roots = myCompilingTests? (Collection<String>)module.getTestRoots() : (Collection<String>)module.getSourceRoots();
// for (String root : roots) {
// final File rootFile = new File(root);
// if (!processRootRecursively(module, rootFile, root, processor, excludes)) {
// return false;
// }
// }
// return true;
//}
private FSSnapshot buildSnapshot(Module module) {
final Set<File> excludes = new HashSet<File>();
for (String excludePath : (Collection<String>)module.getExcludes()) {
@@ -114,25 +164,6 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
return snapshot;
}
//private static boolean processRootRecursively(final Module module, final File fromFile, final String sourceRoot, FileProcessor processor, final Set<File> excluded) throws Exception {
// if (fromFile.isDirectory()) {
// if (isExcluded(excluded, fromFile)) {
// return true;
// }
// final File[] children = fromFile.listFiles();
// if (children != null) {
// for (File child : children) {
// final boolean shouldContinue = processRootRecursively(module, child, sourceRoot, processor, excluded);
// if (!shouldContinue) {
// return false;
// }
// }
// }
// return true;
// }
// return processor.apply(module, fromFile, sourceRoot);
//}
private static void buildStructure(final FSSnapshot.Node from, final Set<File> excluded) {
final File nodeFile = from.getFile();
if (nodeFile.isDirectory()) {
@@ -1,31 +1,39 @@
package org.jetbrains.jps.incremental;
import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.ether.dependencyView.Mappings;
import org.jetbrains.jps.*;
import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.CompilerMessage;
import org.jetbrains.jps.incremental.messages.ProgressMessage;
import java.util.ArrayList;
import java.util.List;
import java.io.*;
import java.util.*;
import java.util.zip.DeflaterOutputStream;
/**
* @author Eugene Zhuravlev
* Date: 9/17/11
*/
public class IncProjectBuilder {
public static final String JPS_SERVER_NAME = "JPS BUILD";
private final Project myProject;
private final String myProjectName;
private final BuilderRegistry myBuilderRegistry;
private ProjectChunks myProductionChunks;
private ProjectChunks myTestChunks;
private final List<MessageHandler> myMessageHandlers = new ArrayList<MessageHandler>();
private final Mappings myMappings;
public IncProjectBuilder(Project project, String projectName, BuilderRegistry builderRegistry) {
myProject = project;
public IncProjectBuilder(String projectName,
Project project,
final Mappings mappings,
BuilderRegistry builderRegistry) {
myProjectName = projectName;
myBuilderRegistry = builderRegistry;
myProductionChunks = new ProjectChunks(project, ClasspathKind.PRODUCTION_COMPILE);
myTestChunks = new ProjectChunks(project, ClasspathKind.TEST_COMPILE);
myMappings = mappings;
}
public void addMessageHandler(MessageHandler handler) {
@@ -33,7 +41,9 @@ public class IncProjectBuilder {
}
public void build(CompileScope scope, final boolean isMake) {
final CompileContext context = new CompileContext(scope, myProjectName, isMake, new MessageHandler() {
final CompileContext context = new CompileContext(
scope, myProjectName, isMake, myMappings, myProductionChunks, myTestChunks, new MessageHandler() {
public void processMessage(BuildMessage msg) {
for (MessageHandler h : myMessageHandlers) {
h.processMessage(msg);
@@ -41,30 +51,111 @@ public class IncProjectBuilder {
}
});
try {
if (!isMake) {
context.getBuildDataManager().clean();
}
for (Module module : scope.getAffectedModules()) {
//context.processMessage(new ProgressMessage("Cleaning module " + module.getName()));
//myProject.cleanModule(module);
}
cleanOutputRoots(scope, context);
context.processMessage(new ProgressMessage("Running 'before' tasks"));
runTasks(context, myBuilderRegistry.getBeforeTasks());
context.setCompilingTests(false);
context.processMessage(new ProgressMessage("Building production sources"));
buildChunks(context, myProductionChunks);
context.setCompilingTests(true);
context.processMessage(new ProgressMessage("Building test sources"));
buildChunks(context, myTestChunks);
context.processMessage(new ProgressMessage("Running 'after' tasks"));
runTasks(context, myBuilderRegistry.getAfterTasks());
}
catch (ProjectBuildException e) {
context.processMessage(new ProgressMessage(e.getMessage()));
}
finally {
context.processMessage(new ProgressMessage("Build complete"));
context.getBuildDataManager().close();
final File mappingsDataFile = Paths.getMappingsStorageFile(myProjectName);
try {
FileUtil.createIfDoesntExist(mappingsDataFile);
final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new DeflaterOutputStream(new FileOutputStream(mappingsDataFile))));
try {
context.getMappings().write(writer);
}
finally {
writer.close();
}
}
catch (IOException e) {
context.processMessage(new CompilerMessage(JPS_SERVER_NAME, BuildMessage.Kind.WARNING, e.getMessage()));
}
}
}
private static void cleanOutputRoots(CompileScope scope, CompileContext context) {
final Collection<Module> allProjectModules = scope.getProject().getModules().values();
final Collection<Module> modulesToClean = new HashSet<Module>();
if (context.isMake()) {
for (Module module : scope.getAffectedModules()) {
if (context.isDirty(module)) {
modulesToClean.add(module);
}
}
}
else {
modulesToClean.addAll(scope.getAffectedModules());
final Set<Module> allModules = new HashSet<Module>(allProjectModules);
allModules.removeAll(scope.getAffectedModules());
if (allModules.isEmpty()) {
// whole project is affected
context.getBuildDataManager().clean();
}
}
if (!modulesToClean.isEmpty()) {
final Set<File> toDelete = new HashSet<File>();
final Set<File> allSourceRoots = new HashSet<File>();
for (Module module : modulesToClean) {
final File out = context.getProjectPaths().getModuleOutputDir(module, false);
if (out != null) {
toDelete.add(out);
}
final File testOut = context.getProjectPaths().getModuleOutputDir(module, true);
if (testOut != null) {
toDelete.add(testOut);
}
}
for (Module module : allProjectModules) {
for (Object root : module.getSourceRoots()) {
allSourceRoots.add(new File((String)root));
}
for (Object root : module.getTestRoots()) {
allSourceRoots.add(new File((String)root));
}
}
// check that output and source roots are not overlapping
for (File outputRoot : toDelete) {
boolean okToDelete = true;
if (PathUtil.isUnder(allSourceRoots, outputRoot)) {
okToDelete = false;
}
else {
final Set<File> _outRoot = Collections.singleton(outputRoot);
for (File srcRoot : allSourceRoots) {
if (PathUtil.isUnder(_outRoot, srcRoot)) {
okToDelete = false;
break;
}
}
}
if (okToDelete) {
context.processMessage(new ProgressMessage("Cleaning " + outputRoot.getPath()));
FileUtil.delete(outputRoot);
}
else {
context.processMessage(new CompilerMessage(JPS_SERVER_NAME, BuildMessage.Kind.WARNING, "Output path " + outputRoot.getPath() + " intersects with a source root. The output cannot be cleaned."));
}
}
}
}
@@ -99,10 +190,6 @@ public class IncProjectBuilder {
do {
nextPassRequired = false;
for (Builder builder : builders) {
//final String sourcesKind = context.isCompilingTests() ? "test" : "production";
//context.processMessage(new ProgressMessage("Compiling " + chunk.getName() + "[" + sourcesKind+"]; Compiler: " + builder.getDescription()));
final Builder.ExitCode buildResult = builder.build(context, chunk);
if (buildResult == Builder.ExitCode.ABORT) {
throw new ProjectBuildException("Builder " + builder.getDescription() + " requested build stop");
@@ -0,0 +1,40 @@
package org.jetbrains.jps.incremental;
import java.io.File;
import java.util.Locale;
/**
* @author Eugene Zhuravlev
* Date: 10/20/11
*/
public class Paths {
private static final Paths ourInstance = new Paths();
private volatile File mySystemRoot = new File(System.getProperty("user.home", ".jps-server"));
private Paths() {
}
public static Paths getInstance() {
return ourInstance;
}
public File getSystemRoot() {
return mySystemRoot;
}
public void setSystemRoot(File systemRoot) {
mySystemRoot = systemRoot;
}
public static File getDataStorageRoot(String projectName) {
return new File(getInstance().mySystemRoot, projectName.toLowerCase(Locale.US));
}
public static File getBuilderDataRoot(final String projectName, String builderName) {
return new File(getDataStorageRoot(projectName), builderName.toLowerCase(Locale.US));
}
public static File getMappingsStorageFile(final String projectName) {
return new File(getDataStorageRoot(projectName), "mappings/data");
}
}
@@ -1,23 +0,0 @@
package org.jetbrains.jps.incremental.forms;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.incremental.Builder;
import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.incremental.ProjectBuildException;
/**
* @author Eugene Zhuravlev
* Date: 10/10/11
*/
public class FormsBuilder extends Builder {
public static final String BUILDER_NAME = "forms";
public ExitCode build(CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
return null;
}
public String getDescription() {
return "UI Designer Forms Builder";
}
}
@@ -1,8 +1,10 @@
package org.jetbrains.jps.incremental.java;
import com.intellij.openapi.util.SystemInfo;
import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.CompilerMessage;
import org.jetbrains.jps.server.ClasspathBootstrap;
import javax.tools.*;
import java.io.File;
@@ -66,6 +68,7 @@ public class EmbeddedJavac {
}
}
//noinspection IOResourceOpenedButNotSafelyClosed
final LineOutputWriter out = new LineOutputWriter() {
protected void lineAvailable(String line) {
outConsumer.outputLineAvailable(line);
@@ -121,11 +124,16 @@ public class EmbeddedJavac {
}
};
StandardJavaFileManager stdManager = null;
try {
stdManager = (StandardJavaFileManager)Class.forName("org.jetbrains.jps.incremental.java.OptimizedFileManager").newInstance();
}
catch (Throwable e) {
compileContext.processMessage(new CompilerMessage("Javac", BuildMessage.Kind.INFO, "Failed to load JPS optimized file manager for javac: " + e.getMessage()));
final Class<StandardJavaFileManager> optimizedManagerClass = ClasspathBootstrap.getOptimizedFileManagerClass();
if (optimizedManagerClass != null) {
try {
stdManager = optimizedManagerClass.newInstance();
}
catch (Throwable e) {
if (SystemInfo.isWindows) {
compileContext.processMessage(new CompilerMessage("Javac", BuildMessage.Kind.INFO, "Failed to load JPS optimized file manager for javac: " + e.getMessage()));
}
}
}
if (stdManager != null) {
myStdManager = stdManager;
@@ -2,6 +2,7 @@ package org.jetbrains.jps.incremental.java;
import com.intellij.compiler.notNullVerification.NotNullVerifyingInstrumenter;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.uiDesigner.compiler.*;
@@ -9,6 +10,8 @@ import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.lw.CompiledClassPropertiesProvider;
import com.intellij.uiDesigner.lw.LwRootContainer;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.ether.dependencyView.Callbacks;
import org.jetbrains.ether.dependencyView.Mappings;
import org.jetbrains.jps.Module;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.ProjectPaths;
@@ -54,15 +57,39 @@ public class JavaBuilder extends Builder{
}
};
private static final Key<Callbacks.Backend> DELTA_MAPPINGS_CALLBACK_KEY = Key.create("_dependency_data_");
private static final Key<Set<File>> ALL_AFFECTED_FILES_KEY = Key.create("_all_affected_files_");
private static final Key<Set<File>> ALL_COMPILED_FILES_KEY = Key.create("_all_compiled_files_");
private final EmbeddedJavac myJavacCompiler;
public JavaBuilder(ExecutorService tasksExecutor) {
myJavacCompiler = new EmbeddedJavac(tasksExecutor);
//add here class processors in the sequence they should be executed
//myJavacCompiler.addClassProcessor(new EmbeddedJavac.ClassPostProcessor() {
// public void process(CompileContext context, OutputFileObject out) {
// }
//});
myJavacCompiler.addClassProcessor(new EmbeddedJavac.ClassPostProcessor() {
public void process(CompileContext context, OutputFileObject out) {
final Callbacks.Backend callback = DELTA_MAPPINGS_CALLBACK_KEY.get(context);
if (callback != null) {
final String className = out.getClassName();
final OutputFileObject.Content content = out.getContent();
final File srcFile = out.getSourceFile();
if (srcFile != null && content != null) {
// todo: the callback is not thread-safe?
final ClassReader reader = new ClassReader(content.getBuffer(), content.getOffset(), content.getLength());
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (callback) {
// todo: parse class data out of synchronized block (move it from the 'associate' implementation)
callback.associate(className, Callbacks.getDefaultLookup(FileUtil.toSystemIndependentName(srcFile.getPath())), reader);
}
}
}
}
});
}
@Override
public String getName() {
return BUILDER_NAME;
}
public String getDescription() {
@@ -72,25 +99,28 @@ public class JavaBuilder extends Builder{
public ExitCode build(final CompileContext context, final ModuleChunk chunk) throws ProjectBuildException {
try {
final TimestampStorage tsStorage = context.getBuildDataManager().getTimestampStorage(BUILDER_NAME);
final Set<File> filesToCompile = new HashSet<File>();
final Set<File> filesToCompile = new LinkedHashSet<File>();
final Set<String> removedPaths = new HashSet<String>(); // only collect them in make mode
final List<File> formsToCompile = new ArrayList<File>();
final List<File> upToDatForms = new ArrayList<File>();
final List<File> upToDateForms = new ArrayList<File>();
final Set<String> srcRoots = new HashSet<String>();
final boolean wholeModuleRebuildRequired = context.isDirty(chunk);
context.processFiles(chunk, new FileProcessor() {
public boolean apply(Module module, File file, String sourceRoot) throws Exception {
if (JAVA_SOURCES_FILTER.accept(file)) {
srcRoots.add(sourceRoot);
if (isFileDirty(file, context, tsStorage)) {
if (wholeModuleRebuildRequired || isFileDirty(file, context, tsStorage)) {
filesToCompile.add(file);
}
}
else if (FORM_SOURCES_FILTER.accept(file)){
if (isFileDirty(file, context, tsStorage)) {
if (wholeModuleRebuildRequired || isFileDirty(file, context, tsStorage)) {
formsToCompile.add(file);
}
else {
upToDatForms.add(file);
upToDateForms.add(file);
}
}
return true;
@@ -110,7 +140,7 @@ public class JavaBuilder extends Builder{
}
// form should be considered dirty if the class it is bound to is also dirty!
for (File form : upToDatForms) {
for (File form : upToDateForms) {
for (String root : srcRoots) {
final File boundSource = getBoundSource(root, form);
if (boundSource != null && filesToCompile.contains(boundSource)) {
@@ -119,9 +149,11 @@ public class JavaBuilder extends Builder{
}
}
}
upToDatForms.clear();
upToDateForms.clear();
return compile(context, chunk, filesToCompile, formsToCompile);
// todo: collect removed stuff
return compile(context, chunk, filesToCompile, formsToCompile, removedPaths);
}
catch (Exception e) {
String message = e.getMessage();
@@ -130,6 +162,7 @@ public class JavaBuilder extends Builder{
e.printStackTrace(new PrintStream(out));
message = "Internal error: \n" + out.toString();
}
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, message));
throw new ProjectBuildException(message, e);
}
}
@@ -154,15 +187,17 @@ public class JavaBuilder extends Builder{
}
}
private ExitCode compile(final CompileContext context, ModuleChunk chunk, Collection<File> files, Collection<File> forms) throws Exception {
private ExitCode compile(final CompileContext context, ModuleChunk chunk, Collection<File> files, Collection<File> forms, Set<String> removedSources) throws Exception {
ExitCode exitCode = ExitCode.OK;
if (files.isEmpty() && forms.isEmpty()) {
return ExitCode.OK;
return exitCode;
}
ProjectPaths paths = ProjectPaths.KEY.get(context);
if (paths == null) {
ProjectPaths.KEY.set(context, paths = new ProjectPaths(context.getProject()));
}
final ProjectPaths paths = context.getProjectPaths();
final Mappings delta = new Mappings();
DELTA_MAPPINGS_CALLBACK_KEY.set(context, delta.getCallback());
// todo: consider corresponding setting in CompilerWorkspaceConfiguration
final boolean addNotNullAssertions = true;
@@ -174,10 +209,21 @@ public class JavaBuilder extends Builder{
final TimestampStorage tsStorage = context.getBuildDataManager().getTimestampStorage(BUILDER_NAME);
Set<File> allCompiledFiles = ALL_COMPILED_FILES_KEY.get(context);
if (allCompiledFiles == null) {
allCompiledFiles = new HashSet<File>();
ALL_COMPILED_FILES_KEY.set(context, allCompiledFiles);
}
Set<File> allAffectedFiles = ALL_AFFECTED_FILES_KEY.get(context);
if (allAffectedFiles == null) {
allAffectedFiles = new HashSet<File>();
ALL_AFFECTED_FILES_KEY.set(context, allAffectedFiles);
}
// begin compilation round
final DiagnosticSink diagnosticSink = new DiagnosticSink(context);
final OutputFilesSink outputSink = new OutputFilesSink(context);
Collection<File> successfulForms = Collections.emptyList();
try {
boolean compiledOk = myJavacCompiler.compile(options, files, classpath, platformCp, outs, context, diagnosticSink, outputSink);
@@ -208,19 +254,71 @@ public class JavaBuilder extends Builder{
if (!compiledOk || diagnosticSink.getErrorCount() > 0) {
throw new ProjectBuildException("Compilation failed: errors: " + diagnosticSink.getErrorCount() + "; warnings: " + diagnosticSink.getWarningCount());
}
return ExitCode.OK;
}
finally {
context.setDirty(chunk, false); // no matter what result was, we should clear this flag
outputSink.writePendingData();
for (File file : outputSink.getSuccessfullyCompiled()) {
final Set<File> successfullyCompiled = outputSink.getSuccessfullyCompiled();
final Mappings globalMappings = context.getMappings();
if (context.isMake()) {
DELTA_MAPPINGS_CALLBACK_KEY.set(context, null);
// mark as affected all files that were dirty before compilation
allAffectedFiles.addAll(files);
// accumulate all successfully compiled in this round
allCompiledFiles.addAll(successfullyCompiled);
// unmark as affected all successfully compiled
allAffectedFiles.removeAll(successfullyCompiled);
final boolean incremental = globalMappings.differentiate(
delta, removedSources, successfullyCompiled, allCompiledFiles, allAffectedFiles
);
if (incremental) {
final Set<File> newlyAffectedFiles = new HashSet<File>(allAffectedFiles);
newlyAffectedFiles.removeAll(allCompiledFiles);
for (File file : newlyAffectedFiles) {
tsStorage.markDirty(file);
}
if (chunkContainsAffectedFiles(context, chunk, newlyAffectedFiles)) {
exitCode = ExitCode.ADDITIONAL_PASS_REQUIRED;
}
}
else {
exitCode = ExitCode.ADDITIONAL_PASS_REQUIRED;
// todo: mark as dirty also all those that depend on this module recursively
context.setDirty(chunk, true);
}
}
globalMappings.integrate(delta, successfullyCompiled, removedSources);
for (File file : successfullyCompiled) {
tsStorage.saveStamp(file);
}
for (File file : successfulForms) {
tsStorage.saveStamp(file);
}
}
return exitCode;
}
private static boolean chunkContainsAffectedFiles(CompileContext context, ModuleChunk chunk, final Set<File> affected) throws Exception {
final Ref<Boolean> result = new Ref<Boolean>(false);
context.processFiles(chunk, new FileProcessor() {
public boolean apply(Module module, File file, String sourceRoot) throws Exception {
if (affected.contains(file)) {
result.set(true);
return false;
}
return true;
}
});
return result.get();
}
private static ClassLoader createInstrumentationClassLoader(Collection<File> classpath, Collection<File> platformCp, Collection<File> chunkSourcePath, OutputFilesSink outputSink)
@@ -23,6 +23,11 @@ public class ResourcesBuilder extends Builder{
public ResourcesBuilder() {
}
@Override
public String getName() {
return BUILDER_NAME;
}
public ExitCode build(final CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
CompilerConfiguration config = null;
for (Module module : chunk.getModules()) {
@@ -2,6 +2,7 @@ package org.jetbrains.jps.incremental.storage;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.jps.incremental.Paths;
import java.io.File;
import java.io.IOException;
@@ -14,22 +15,20 @@ import java.util.Map;
*/
public class BuildDataManager {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.storage.BuildDataManager");
private static final String TIMESTAMP_STORAGE = "stamps";
private final String myProjectName;
public static final String TIMESTAMP_STORAGE = "timestamps";
private final File myDataRoot;
private final Map<String, TimestampStorage> myBuilderToStampStorageMap = new HashMap<String, TimestampStorage>();
//private final Map<String, AbstractStateStorage> myBuilderToStorageMap = new HashMap<String, AbstractStateStorage>();
public BuildDataManager(File dataRoot) {
myDataRoot = dataRoot;
public BuildDataManager(String projectName) {
myProjectName = projectName;
}
public TimestampStorage getTimestampStorage(String builderName) throws IOException {
synchronized (myBuilderToStampStorageMap) {
TimestampStorage storage = myBuilderToStampStorageMap.get(builderName);
if (storage == null) {
storage = new TimestampStorage(getStoreFile(builderName, TIMESTAMP_STORAGE));
storage = new TimestampStorage(new File(getTimestampsStorageRoot(builderName), "data"));
myBuilderToStampStorageMap.put(builderName, storage);
}
return storage;
@@ -39,7 +38,7 @@ public class BuildDataManager {
public void clean() {
synchronized (myBuilderToStampStorageMap) {
close();
FileUtil.delete(myDataRoot);
FileUtil.delete(Paths.getDataStorageRoot(myProjectName));
}
}
@@ -54,7 +53,7 @@ public class BuildDataManager {
LOG.info(e);
}
}
FileUtil.delete(getDataRoot(builderName, TIMESTAMP_STORAGE));
FileUtil.delete(Paths.getBuilderDataRoot(myProjectName, builderName));
}
}
@@ -69,7 +68,7 @@ public class BuildDataManager {
catch (IOException e) {
LOG.error(e);
final String builderName = entry.getKey();
FileUtil.delete(getDataRoot(builderName, TIMESTAMP_STORAGE));
FileUtil.delete(getTimestampsStorageRoot(builderName));
}
}
}
@@ -79,15 +78,7 @@ public class BuildDataManager {
}
}
private File getStoreFile(String builderName, String storageName) {
return new File(getDataRoot(builderName, storageName), "data");
public File getTimestampsStorageRoot(String builderName) {
return new File(Paths.getBuilderDataRoot(myProjectName, builderName), TIMESTAMP_STORAGE);
}
private File getDataRoot(String builderName, String storageName) {
return new File(myDataRoot, builderName + File.separator + storageName);
}
//public <K, V> AbstractStateStorage<K, V> getStorage(String builderName) {
//
//}
}
@@ -32,6 +32,10 @@ public class TimestampStorage extends AbstractStateStorage<File, TimestampValidi
update(file, new TimestampValidityState(timestamp));
}
public void markDirty(File file) throws IOException {
update(file, null);
}
private static class FileKeyDescriptor implements KeyDescriptor<File> {
private final byte[] buffer = IOUtil.allocReadWriteUTFBuffer();
@@ -24,9 +24,11 @@ import com.jgoodies.forms.layout.CellConstraints;
import gnu.trove.TIntHash;
import net.n3.nanoxml.IXMLBuilder;
import org.codehaus.groovy.GroovyException;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.MacroExpander;
import org.objectweb.asm.ClassWriter;
import javax.tools.*;
import java.io.File;
import java.util.ArrayList;
import java.util.LinkedHashSet;
@@ -38,10 +40,28 @@ import java.util.Set;
* Date: 9/12/11
*/
public class ClasspathBootstrap {
private ClasspathBootstrap() {
public static final String JPS_RUNTIME_PATH = "rt/jps-incremental";
private static class OptimizedFileManagerClassHolder {
static final String CLASS_NAME = "org.jetbrains.jps.incremental.java.OptimizedFileManager";
static final Class<StandardJavaFileManager> managerClass;
static {
Class<StandardJavaFileManager> aClass = null;
try {
aClass = (Class<StandardJavaFileManager>)Class.forName(CLASS_NAME);
}
catch (Throwable e) {
aClass = null;
}
managerClass = aClass;
}
private OptimizedFileManagerClassHolder() {
}
}
public static final String JPS_RUNTIME_PATH = "rt/jps-incremental";
private ClasspathBootstrap() {
}
public static List<File> getApplicationClasspath() {
final Set<File> cp = new LinkedHashSet<File>();
@@ -61,6 +81,11 @@ public class ClasspathBootstrap {
cp.add(getResourcePath(NotNullVerifyingInstrumenter.class)); // not-null
cp.add(getResourcePath(IXMLBuilder.class)); // nano-xml
final Class<StandardJavaFileManager> optimizedFileManagerClass = getOptimizedFileManagerClass();
if (optimizedFileManagerClass != null) {
cp.add(getResourcePath(optimizedFileManagerClass)); // optimizedFileManager
}
//final File jpsRuntime = new File(jpsFacadeJar.getParentFile(), JPS_RUNTIME_PATH);
//final File[] files = jpsRuntime.listFiles();
//if (files != null) {
@@ -85,6 +110,11 @@ public class ClasspathBootstrap {
return new ArrayList<File>(cp);
}
@Nullable
public static Class<StandardJavaFileManager> getOptimizedFileManagerClass() {
return OptimizedFileManagerClassHolder.managerClass;
}
public static File getResourcePath(Class aClass) {
return new File(PathManager.getResourceRoot(aClass, "/" + aClass.getName().replace('.', '/') + ".class"));
}
@@ -11,7 +11,9 @@ import org.jboss.netty.handler.codec.protobuf.ProtobufEncoder;
import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import org.jetbrains.jps.api.JpsRemoteProto;
import org.jetbrains.jps.incremental.Paths;
import java.io.File;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -31,7 +33,8 @@ public class Server {
private final ChannelPipelineFactory myPipelineFactory;
private final ExecutorService myBuildsExecutor;
public Server() {
public Server(File systemDir) {
Paths.getInstance().setSystemRoot(systemDir);
final ExecutorService threadPool = Executors.newCachedThreadPool();
myBuildsExecutor = Executors.newFixedThreadPool(MAX_SIMULTANEOUS_BUILD_SESSIONS);
myChannelFactory = new NioServerSocketChannelFactory(threadPool, threadPool, 1);
@@ -74,7 +77,7 @@ public class Server {
public static void main(String[] args) {
try {
int port = DEFAULT_SERVER_PORT;
File systemDir = null;
if (args.length > 0) {
try {
port = Integer.parseInt(args[0]);
@@ -83,9 +86,11 @@ public class Server {
System.err.println("Error parsing port: " + e.getMessage());
System.exit(-1);
}
systemDir = new File(args[1]);
}
final Server server = new Server();
final Server server = new Server(systemDir);
server.start(port);
Runtime.getRuntime().addShutdownHook(new Thread("Shutdown hook thread") {
public void run() {
@@ -1,6 +1,7 @@
package org.jetbrains.jps.server;
import org.codehaus.groovy.runtime.MethodClosure;
import org.jetbrains.ether.dependencyView.Mappings;
import org.jetbrains.jps.JavaSdk;
import org.jetbrains.jps.Library;
import org.jetbrains.jps.Module;
@@ -9,13 +10,13 @@ import org.jetbrains.jps.api.BuildParameters;
import org.jetbrains.jps.api.GlobalLibrary;
import org.jetbrains.jps.api.SdkLibrary;
import org.jetbrains.jps.idea.IdeaProjectLoader;
import org.jetbrains.jps.incremental.BuilderRegistry;
import org.jetbrains.jps.incremental.CompileScope;
import org.jetbrains.jps.incremental.IncProjectBuilder;
import org.jetbrains.jps.incremental.MessageHandler;
import org.jetbrains.jps.incremental.*;
import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.CompilerMessage;
import java.io.File;
import java.io.*;
import java.util.*;
import java.util.zip.DeflaterInputStream;
/**
* @author Eugene Zhuravlev
@@ -26,6 +27,8 @@ class ServerState {
public static final String IDEA_PROJECT_DIRNAME = ".idea";
private final Map<String, Project> myProjects = new HashMap<String, Project>();
private final Map<String, Mappings> myProjectMappings = new HashMap<String, Mappings>();
private final Object myConfigurationLock = new Object();
private final Map<String, String> myPathVariables = new HashMap<String, String>();
private final List<GlobalLibrary> myGlobalLibraries = new ArrayList<GlobalLibrary>();
@@ -43,18 +46,44 @@ class ServerState {
public void clearProjectCache(Collection<String> projectPaths) {
synchronized (myConfigurationLock) {
myProjects.keySet().removeAll(projectPaths);
myProjectMappings.keySet().removeAll(projectPaths);
}
}
public void startBuild(String projectPath, Set<String> modules, final BuildParameters params, final MessageHandler msgHandler) throws Throwable{
Project project;
final String projectName = getProjectName(projectPath);
Project project;
Mappings mappings;
synchronized (myConfigurationLock) {
project = myProjects.get(projectPath);
if (project == null) {
project = loadProject(projectPath, params);
myProjects.put(projectPath, project);
}
mappings = myProjectMappings.get(projectPath);
if (mappings == null) {
final File mappingsStorageFile = Paths.getMappingsStorageFile(projectName);
try {
final BufferedReader reader = new BufferedReader(new InputStreamReader(new DeflaterInputStream(new FileInputStream(mappingsStorageFile))));
try {
mappings = new Mappings(reader);
}
finally {
reader.close();
}
}
catch (FileNotFoundException e) {
mappings = new Mappings();
}
catch (IOException e) {
msgHandler.processMessage(new CompilerMessage(IncProjectBuilder.JPS_SERVER_NAME, BuildMessage.Kind.WARNING, e.getMessage()));
mappings = new Mappings();
}
myProjectMappings.put(projectPath, mappings);
}
}
final List<Module> toCompile = new ArrayList<Module>();
@@ -75,7 +104,7 @@ class ServerState {
}
};
final IncProjectBuilder builder = new IncProjectBuilder(project, getProjectName(projectPath), BuilderRegistry.getInstance());
final IncProjectBuilder builder = new IncProjectBuilder(projectName, project, mappings, BuilderRegistry.getInstance());
if (msgHandler != null) {
builder.addMessageHandler(msgHandler);
}
Binary file not shown.
+1
View File
@@ -9,6 +9,7 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="Groovy" level="project" />
<orderEntry type="module" module-name="util" />
<orderEntry type="library" name="asm" level="project" />
</component>
</module>
+258
View File
@@ -0,0 +1,258 @@
package org.jetbrains.ether;
import com.intellij.util.xmlb.XmlSerializationException;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 29.01.11
* Time: 21:10
* To change this template use File | Settings | File Templates.
*/
public class RW {
public interface Writable {
public void write(BufferedWriter w);
}
public static <T extends Comparable> void writeln(final BufferedWriter w, final Collection<T> c, final ToWritable<T> t) {
if (c == null) {
writeln(w, "0");
return;
}
writeln(w, Integer.toString(c.size()));
for (T e : c) {
t.convert(e).write(w);
}
}
public static void writeEncodedString(final BufferedWriter w, final String val) {
final int size = val == null ? 0 : val.length();
writeln(w, Integer.toString(size));
for (int i = 0; i < size; i++) {
writeln(w, Integer.toString((int)val.charAt(i)));
}
}
public static void writeln(final BufferedWriter w, final Collection<? extends Writable> c) {
if (c == null) {
writeln(w, "0");
return;
}
writeln(w, Integer.toString(c.size()));
for (Writable e : c) {
e.write(w);
}
}
public interface ToWritable<T> {
public Writable convert(T x);
}
public static <T> void writeln(final BufferedWriter w, final T[] c, final ToWritable<T> t) {
if (c == null) {
writeln(w, "0");
return;
}
writeln(w, Integer.toString(c.length));
for (int i = 0; i < c.length; i++) {
t.convert(c[i]).write(w);
}
}
public static <T extends Writable> void writeln(final BufferedWriter w, final T[] c) {
if (c == null) {
writeln(w, "0");
return;
}
writeln(w, Integer.toString(c.length));
for (int i = 0; i < c.length; i++) {
c[i].write(w);
}
}
public static void writeln(final BufferedWriter w, final String s) {
try {
if (s == null) {
w.write("");
}
else {
w.write(s);
}
w.newLine();
}
catch (IOException e) {
e.printStackTrace();
}
}
public static <X extends Writable, Y extends Writable> void writeMap (final BufferedWriter w, final Map<X, Y> m) {
final int size = m.size();
writeln(w, Integer.toString(size));
for (Map.Entry<X, Y> e : m.entrySet()) {
e.getKey().write(w);
e.getValue().write(w);
}
}
public interface Reader<T> {
public T read(BufferedReader r);
}
public static ToWritable<String> fromString = new ToWritable<String>() {
public Writable convert(final String s) {
return new Writable() {
public void write(BufferedWriter w) {
writeln(w, s);
}
};
}
};
public static ToWritable<Writable> fromWritable = new ToWritable<Writable>() {
public Writable convert(final Writable w) {
return w;
}
};
public static Reader<String> myStringReader = new Reader<String>() {
public String read(final BufferedReader r) {
try {
return r.readLine();
}
catch (IOException e) {
e.printStackTrace();
return null;
}
}
};
public static <T> Collection<T> readMany(final BufferedReader r, final Reader<T> c, final Collection<T> acc) {
final int size = readInt(r);
for (int i = 0; i < size; i++) {
acc.add(c.read(r));
}
return acc;
}
public static String lookString(final BufferedReader r) {
try {
r.mark(256);
final String s = r.readLine();
r.reset();
return s;
}
catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static void readTag(final BufferedReader r, final String tag) {
try {
final String s = r.readLine();
if (!s.equals(tag)) System.err.println("Parsing error: expected \"" + tag + "\", but found \"" + s + "\"");
}
catch (IOException e) {
e.printStackTrace();
}
}
public static String readString(final BufferedReader r) {
try {
return r.readLine();
}
catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static String readEncodedString(final BufferedReader r) {
final StringBuilder b = new StringBuilder();
final int size = readInt(r);
for (int i = 0; i < size; i++) {
final int c = readInt(r);
b.append((char)c);
}
return b.toString();
}
public static long readLong(final BufferedReader r) {
final String s = readString(r);
try {
return Long.parseLong(s);
}
catch (Exception n) {
System.err.println("Parsing error: expected long, but found \"" + s + "\"");
return 0;
}
}
public static int readInt(final BufferedReader r) {
final String s = readString(r);
try {
return Integer.parseInt(s);
}
catch (Exception n) {
System.err.println("Parsing error: expected integer, but found \"" + s + "\"");
return 0;
}
}
public static String readStringAttribute(final BufferedReader r, final String tag) {
try {
final String s = r.readLine();
if (s.startsWith(tag)) return s.substring(tag.length());
System.err.println("Parsing error: expected \"" + tag + "\", but found \"" + s + "\"");
return null;
}
catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static <X, Y> Map<X, Y> readMap (final BufferedReader r, final Reader<X> xr, final Reader<Y> yr, final Map<X, Y> acc) {
final int size = RW.readInt(r);
for (int i = 0; i<size; i++) {
final X key = xr.read(r);
final Y value = yr.read(r);
acc.put(key, value);
}
return acc;
}
}
@@ -0,0 +1,40 @@
package org.jetbrains.ether.dependencyView;
import com.intellij.openapi.util.Pair;
import org.objectweb.asm.ClassReader;
import java.util.Collection;
import java.util.Set;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 28.01.11
* Time: 15:55
* To change this template use File | Settings | File Templates.
*/
public class Callbacks {
public interface SourceFileNameLookup {
String get(String sourceAttribute);
}
public static SourceFileNameLookup getDefaultLookup(final String name) {
return new SourceFileNameLookup() {
public String get(final String sourceAttribute) {
return name;
}
};
}
public interface Backend {
Collection<StringCache.S> getClassFiles();
void associate(String classFileName, SourceFileNameLookup sourceLookup, ClassReader cr);
void associate(Set<Pair<ClassRepr, Set<StringCache.S>>> classes,
Pair<UsageRepr.Cluster, Set<UsageRepr.Usage>> usages,
String sourceFileName);
void associateForm(StringCache.S formName, StringCache.S className);
}
}
@@ -1,7 +1,6 @@
package org.jetbrains.ether.dependencyView;
import com.sun.org.apache.bcel.internal.generic.PUTFIELD;
import org.jetbrains.ether.Pair;
import com.intellij.openapi.util.Pair;
import org.objectweb.asm.*;
import org.objectweb.asm.commons.EmptyVisitor;
import org.objectweb.asm.signature.SignatureReader;
@@ -0,0 +1,118 @@
package org.jetbrains.ether.dependencyView;
import com.intellij.openapi.util.Pair;
import java.util.*;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 01.03.11
* Time: 17:39
* To change this template use File | Settings | File Templates.
*/
public abstract class Difference {
public static final int NONE = 0;
public static final int ACCESS = 1;
public static final int TYPE = 2;
public static final int VALUE = 4;
public static final int SIGNATURE = 8;
public static final int SUPERCLASS = 16;
public interface Specifier<T> {
public Collection<T> added();
public Collection<T> removed();
public Collection<Pair<T, Difference>> changed();
public boolean unchanged();
}
public static <T> Specifier<T> make(final Set<T> past, final Set<T> now) {
if (past == null) {
final Collection<T> removed = new HashSet<T>();
final Collection<Pair<T, Difference>> changed = new HashSet<Pair<T, Difference>>();
return new Specifier<T>() {
public Collection<T> added() {
return now;
}
public Collection<T> removed() {
return removed;
}
public Collection<Pair<T, Difference>> changed() {
return changed;
}
public boolean unchanged() {
return false;
}
};
}
final Set<T> added = new HashSet<T>(now);
added.removeAll(past);
final Set<T> removed = new HashSet<T>(past);
removed.removeAll(now);
final Set<Pair<T, Difference>> changed = new HashSet<Pair<T, Difference>>();
final Set<T> intersect = new HashSet<T>(past);
final Map<T, T> nowMap = new HashMap<T, T>();
for (T s : now) {
if (intersect.contains(s)) {
nowMap.put(s, s);
}
}
intersect.retainAll(now);
for (T x : intersect) {
final T y = nowMap.get(x);
if (x instanceof Proto) {
final Proto px = (Proto)x;
final Proto py = (Proto)y;
final Difference diff = py.difference(px);
if (!diff.no()) {
changed.add(new Pair<T, Difference>(x, diff));
}
}
}
return new Specifier<T>() {
public Collection<T> added() {
return added;
}
public Collection<T> removed() {
return removed;
}
public Collection<Pair<T, Difference>> changed() {
return changed;
}
public boolean unchanged() {
return changed.isEmpty() && added.isEmpty() && removed.isEmpty();
}
};
}
public abstract int base();
public abstract boolean no();
public abstract int addedModifiers();
public abstract int removedModifiers();
public abstract boolean packageLocalOn();
}
@@ -0,0 +1,56 @@
package org.jetbrains.ether.dependencyView;
import org.jetbrains.ether.RW;
import java.io.BufferedReader;
import java.util.Set;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 01.02.11
* Time: 4:56
* To change this template use File | Settings | File Templates.
*/
public class FieldRepr extends ProtoMember {
public void updateClassUsages(final Set<UsageRepr.Usage> s) {
type.updateClassUsages(s);
}
public FieldRepr(final int a, final String n, final String d, final String s, final Object v) {
super(a, s, StringCache.get(n), TypeRepr.getType(d), v);
}
public FieldRepr(final BufferedReader r) {
super(r);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final FieldRepr fieldRepr = (FieldRepr)o;
return name.equals(fieldRepr.name);
}
@Override
public int hashCode() {
return 31 * name.hashCode();
}
public static RW.Reader<FieldRepr> reader = new RW.Reader<FieldRepr>() {
public FieldRepr read(final BufferedReader r) {
return new FieldRepr(r);
}
};
public UsageRepr.Usage createUsage(final StringCache.S owner) {
return UsageRepr.createFieldUsage(name.value, owner.value, type.getDescr());
}
public UsageRepr.Usage createAssignUsage(final StringCache.S owner) {
return UsageRepr.createFieldAssignUsage(name.value, owner.value, type.getDescr());
}
}
@@ -0,0 +1,181 @@
package org.jetbrains.ether.dependencyView;
import org.jetbrains.ether.RW;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.util.*;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 08.03.11
* Time: 15:38
* To change this template use File | Settings | File Templates.
*/
public class FoxyMap<K, V> implements Map<K, Object> {
public static <X extends RW.Writable, Y extends RW.Writable> void write (final BufferedWriter w, final FoxyMap<X, Y> m){
RW.writeln(w, Integer.toString(m.size()));
for (Entry<X, Object> e : m.entrySet()) {
e.getKey().write(w);
final Object value = e.getValue();
if (value instanceof Collection) {
RW.writeln(w, "many");
RW.writeln(w, (Collection<Y>) value);
} else {
RW.writeln(w, "single");
((Y) value).write(w);
}
}
}
public static <X, Y> FoxyMap<X,Y> read (final BufferedReader r, final RW.Reader<X> xr, final RW.Reader<Y> yr, final CollectionConstructor<Y> cc){
final FoxyMap<X, Y> result = new FoxyMap<X,Y>(cc);
final int size = RW.readInt(r);
for (int i=0; i<size; i++) {
final X key = xr.read(r);
final String tag = RW.readString(r);
if (tag.equals("many")) {
result.put(key, RW.readMany(r, yr, cc.create()));
} else {
result.put(key, yr.read(r));
}
}
return result;
}
public interface CollectionConstructor<X> {
Collection<X> create();
}
private final Map<K, Object> map = new HashMap<K, Object>();
private final CollectionConstructor<V> constr;
public FoxyMap(final CollectionConstructor<V> c) {
constr = c;
}
public int size() {
return map.size();
}
public boolean isEmpty() {
return map.isEmpty();
}
public boolean containsKey(final Object key) {
return map.containsKey(key);
}
public boolean containsValue(final Object value) {
return map.containsValue(value);
}
public Object get(final Object key) {
return map.get(key);
}
public Collection<V> foxyGet(final K key) {
final Object c = get(key);
if (c == null) {
return null;
}
if (c instanceof Collection) {
return (Collection)c;
}
final Collection<V> l = constr.create();
l.add((V)c);
return l;
}
public Object put(final K key, final Object value) {
final Object c = get(key);
if (c == null) {
map.put(key, value);
}
else {
if (c instanceof Collection) {
if (value instanceof Collection) {
((Collection)c).addAll((Collection)value);
}
else {
((Collection)c).add(value);
}
}
else {
final Collection d = constr.create();
d.add(c);
if (value instanceof Collection) {
d.addAll((Collection)value);
}
else {
d.add(value);
}
map.put(key, d);
}
}
return c;
}
public Object remove(final Object key) {
return map.remove(key);
}
public void putAll(Map<? extends K, ? extends Object> m) {
for (Entry<? extends K, ? extends Object> e : m.entrySet()) {
remove(e.getKey());
put(e.getKey(), e.getValue());
}
}
public void clear() {
map.clear();
}
public Set<K> keySet() {
return map.keySet();
}
public Collection<Object> values() {
final List l = new LinkedList();
for (Object value : map.values()) {
if (value instanceof Collection) {
l.addAll((Collection)value);
}
else {
l.add(value);
}
}
return l;
}
public Collection<V> foxyValues() {
return (Collection<V>)values();
}
public Set<Entry<K, Object>> entrySet() {
return map.entrySet();
}
}
@@ -1,14 +1,16 @@
package org.jetbrains.ether.dependencyView;
import org.codehaus.groovy.transform.DelegateASTTransformation;
import org.jetbrains.ether.Pair;
import org.jetbrains.ether.ProjectWrapper;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.ether.RW;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Opcodes;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.File;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
import java.util.*;
@@ -20,7 +22,7 @@ import java.util.*;
* Time: 16:20
* To change this template use File | Settings | File Templates.
*/
public class Mappings {
public class Mappings implements RW.Writable {
private static FoxyMap.CollectionConstructor<ClassRepr> classSetConstructor = new FoxyMap.CollectionConstructor<ClassRepr>() {
public Collection<ClassRepr> create() {
@@ -40,29 +42,65 @@ public class Mappings {
}
};
private FoxyMap<StringCache.S, StringCache.S> classToSubclasses = new FoxyMap<StringCache.S, StringCache.S>(stringSetConstructor);
private FoxyMap<StringCache.S, ClassRepr> sourceFileToClasses = new FoxyMap<StringCache.S, ClassRepr>(classSetConstructor);
private Map<StringCache.S, UsageRepr.Cluster> sourceFileToUsages = new HashMap<StringCache.S, UsageRepr.Cluster>();
private FoxyMap<StringCache.S, UsageRepr.Usage> sourceFileToAnnotationUsages =
new FoxyMap<StringCache.S, UsageRepr.Usage>(usageSetConstructor);
private Map<StringCache.S, StringCache.S> classToSourceFile = new HashMap<StringCache.S, StringCache.S>();
private FoxyMap<StringCache.S, StringCache.S> fileToFileDependency = new FoxyMap<StringCache.S, StringCache.S>(stringSetConstructor);
private FoxyMap<StringCache.S, StringCache.S> waitingForResolve = new FoxyMap<StringCache.S, StringCache.S>(stringSetConstructor);
private Map<StringCache.S, StringCache.S> formToClass = new HashMap<StringCache.S, StringCache.S>();
private Map<StringCache.S, StringCache.S> classToForm = new HashMap<StringCache.S, StringCache.S>();
private final FoxyMap<StringCache.S, StringCache.S> classToSubclasses;
private final FoxyMap<StringCache.S, ClassRepr> sourceFileToClasses;
private final Map<StringCache.S, UsageRepr.Cluster> sourceFileToUsages;
private final FoxyMap<StringCache.S, UsageRepr.Usage> sourceFileToAnnotationUsages;
private final Map<StringCache.S, StringCache.S> classToSourceFile;
private final FoxyMap<StringCache.S, StringCache.S> fileToFileDependency;
private final FoxyMap<StringCache.S, StringCache.S> waitingForResolve;
private final Map<StringCache.S, StringCache.S> formToClass;
private final Map<StringCache.S, StringCache.S> classToForm;
@Override
public void write(BufferedWriter w) {
FoxyMap.write(w, classToSubclasses);
FoxyMap.write(w, sourceFileToClasses);
RW.writeMap(w, sourceFileToUsages);
FoxyMap.write(w, sourceFileToAnnotationUsages);
RW.writeMap(w, classToSourceFile);
FoxyMap.write(w, fileToFileDependency);
}
public Mappings () {
classToSubclasses = new FoxyMap<StringCache.S, StringCache.S>(stringSetConstructor);
sourceFileToClasses = new FoxyMap<StringCache.S, ClassRepr>(classSetConstructor);
sourceFileToUsages = new HashMap<StringCache.S, UsageRepr.Cluster>();
sourceFileToAnnotationUsages = new FoxyMap<StringCache.S, UsageRepr.Usage>(usageSetConstructor);
classToSourceFile = new HashMap<StringCache.S, StringCache.S>();
fileToFileDependency = new FoxyMap<StringCache.S, StringCache.S>(stringSetConstructor);
waitingForResolve = new FoxyMap<StringCache.S, StringCache.S>(stringSetConstructor);
formToClass = new HashMap<StringCache.S, StringCache.S>();
classToForm = new HashMap<StringCache.S, StringCache.S>();
}
public Mappings (final BufferedReader r) {
classToSubclasses = FoxyMap.read(r, StringCache.reader, StringCache.reader, stringSetConstructor);
sourceFileToClasses = FoxyMap.read(r, StringCache.reader, ClassRepr.reader, classSetConstructor);
sourceFileToUsages = RW.readMap(r, StringCache.reader, UsageRepr.clusterReader, new HashMap<StringCache.S, UsageRepr.Cluster>());
sourceFileToAnnotationUsages = FoxyMap.read(r, StringCache.reader, UsageRepr.reader, usageSetConstructor);
classToSourceFile = RW.readMap(r, StringCache.reader, StringCache.reader, new HashMap<StringCache.S, StringCache.S>());
fileToFileDependency = FoxyMap.read(r, StringCache.reader, StringCache.reader, stringSetConstructor);
waitingForResolve = new FoxyMap<StringCache.S, StringCache.S>(stringSetConstructor);
formToClass = new HashMap<StringCache.S, StringCache.S>();
classToForm = new HashMap<StringCache.S, StringCache.S>();
}
private void compensateRemovedContent(final Collection<StringCache.S> compiled) {
for (StringCache.S name : compiled) {
final Collection<ClassRepr> classes = sourceFileToClasses.foxyGet(name);
if (classes == null) {
if (!sourceFileToClasses.containsKey(name)) {
sourceFileToClasses.put(name, new HashSet<ClassRepr>());
}
}
}
@Nullable
private ClassRepr getReprByName(final StringCache.S name) {
final Collection<ClassRepr> reprs = sourceFileToClasses.foxyGet(classToSourceFile.get(name));
final StringCache.S source = classToSourceFile.get(name);
assert source != null;
final Collection<ClassRepr> reprs = sourceFileToClasses.foxyGet(source);
if (reprs != null) {
for (ClassRepr repr : reprs) {
@@ -255,6 +293,8 @@ public class Mappings {
final boolean usages) {
final StringCache.S fileName = classToSourceFile.get(className);
assert (fileName != null);
if (usages) {
affectedUsages.add(reprByName(className).createUsage());
}
@@ -284,7 +324,16 @@ public class Mappings {
affectedUsages.add(rootUsage);
for (StringCache.S p : subclasses) {
dependents.addAll(fileToFileDependency.foxyGet(classToSourceFile.get(p)));
final StringCache.S source = classToSourceFile.get(p);
assert source != null;
final Collection<StringCache.S> deps = fileToFileDependency.foxyGet(source);
if (deps != null) {
dependents.addAll(deps);
}
affectedUsages.add(rootUsage instanceof UsageRepr.FieldAssignUsage ? field.createAssignUsage(p) : field.createUsage(p));
}
}
@@ -297,7 +346,16 @@ public class Mappings {
affectedUsages.add(rootUsage);
for (StringCache.S p : subclasses) {
dependents.addAll(fileToFileDependency.foxyGet(classToSourceFile.get(p)));
final StringCache.S source = classToSourceFile.get(p);
assert source != null;
final Collection<StringCache.S> deps = fileToFileDependency.foxyGet(source);
if (deps != null) {
dependents.addAll(deps);
}
affectedUsages.add(method.createUsage(p));
}
}
@@ -369,28 +427,33 @@ public class Mappings {
}
}
private Set<StringCache.S> cache (final Collection<String> x) {
private static Set<StringCache.S> cachePaths(final Collection<String> x) {
final Set<StringCache.S> y = new HashSet<StringCache.S>();
for (String s : x) {
y.add(StringCache.get(s));
y.add(StringCache.get(FileUtil.toSystemIndependentName(s)));
}
return y;
}
private static Set<StringCache.S> cacheFiles(final Collection<File> x) {
final Set<StringCache.S> y = new HashSet<StringCache.S>();
for (File s : x) {
y.add(StringCache.get(FileUtil.toSystemIndependentName(s.getAbsolutePath())));
}
return y;
}
public boolean differentiate(final Mappings delta,
final Collection<String> removed,
final Collection<String> filesToCompile,
final Collection<String> compiledFiles,
final Collection<String> affectedFiles,
final Collection<String> safeFiles) {
final Set<StringCache.S> affectedCache = cache(affectedFiles);
final Collection<File> successfullyCompiled,
final Collection<File> allCompiledFiles,
final Collection<File> allAffectedFiles) {
final Set<StringCache.S> affectedCache = cacheFiles(allAffectedFiles);
final boolean result = differentiate(delta, cache(removed), cache(filesToCompile), cache(compiledFiles), affectedCache, cache(safeFiles));
final boolean result = differentiate(delta, cachePaths(removed), cacheFiles(successfullyCompiled), cacheFiles(allCompiledFiles), affectedCache, Collections.<StringCache.S>emptySet());
for (StringCache.S a : affectedCache) {
affectedFiles.add(a.value);
allAffectedFiles.add(new File(a.value));
}
return result;
@@ -420,7 +483,14 @@ public class Mappings {
final Set<ClassRepr> classes = (Set<ClassRepr>)delta.sourceFileToClasses.foxyGet(fileName);
final Set<ClassRepr> pastClasses = (Set<ClassRepr>)sourceFileToClasses.foxyGet(fileName);
final Set<StringCache.S> dependants = (Set<StringCache.S>)fileToFileDependency.foxyGet(fileName);
final Set<StringCache.S> dependants = new HashSet<StringCache.S>();
final Collection<StringCache.S> dep = fileToFileDependency.foxyGet(fileName);
if (dep != null) {
dependants.addAll(dep);
}
final Set<UsageRepr.Usage> affectedUsages = new HashSet<UsageRepr.Usage>();
final Set<UsageRepr.AnnotationUsage> annotationQuery = new HashSet<UsageRepr.AnnotationUsage>();
final Map<UsageRepr.Usage, Util.UsageConstraint> usageConstraints = new HashMap<UsageRepr.Usage, Util.UsageConstraint>();
@@ -428,8 +498,8 @@ public class Mappings {
final Difference.Specifier<ClassRepr> classDiff = Difference.make(pastClasses, classes);
for (Pair<ClassRepr, Difference> changed : classDiff.changed()) {
final ClassRepr it = changed.fst;
final ClassRepr.Diff diff = (ClassRepr.Diff)changed.snd;
final ClassRepr it = changed.first;
final ClassRepr.Diff diff = (ClassRepr.Diff)changed.second;
final int addedModifiers = diff.addedModifiers();
final int removedModifiers = diff.removedModifiers();
@@ -532,12 +602,12 @@ public class Mappings {
boolean visited = false;
for (Pair<MethodRepr, ClassRepr> pp : overridenInS) {
if (pp.snd.name.equals(it.name)) {
if (pp.second.name.equals(it.name)) {
continue;
}
visited = true;
allAbstract = ((pp.fst.access & Opcodes.ACC_ABSTRACT) > 0) || ((pp.snd.access & Opcodes.ACC_INTERFACE) > 0);
allAbstract = ((pp.first.access & Opcodes.ACC_ABSTRACT) > 0) || ((pp.second.access & Opcodes.ACC_INTERFACE) > 0);
if (!allAbstract) {
break;
@@ -545,7 +615,11 @@ public class Mappings {
}
if (allAbstract && visited) {
affectedFiles.add(classToSourceFile.get(p));
final StringCache.S source = classToSourceFile.get(p);
assert source != null;
affectedFiles.add(source);
}
}
}
@@ -553,8 +627,8 @@ public class Mappings {
}
for (Pair<MethodRepr, Difference> mr : diff.methods().changed()) {
final MethodRepr m = mr.fst;
final MethodRepr.Diff d = (MethodRepr.Diff)mr.snd;
final MethodRepr m = mr.first;
final MethodRepr.Diff d = (MethodRepr.Diff)mr.second;
final boolean throwsChanged = (d.exceptions().added().size() > 0) || (d.exceptions().changed().size() > 0);
if (it.isAnnotation()) {
@@ -621,11 +695,12 @@ public class Mappings {
final Collection<StringCache.S> subClasses = getSubClasses(it.name);
if (subClasses != null) {
for (StringCache.S subClass : subClasses) {
for (final StringCache.S subClass : subClasses) {
final ClassRepr r = u.reprByName(subClass);
final StringCache.S sourceFileName = classToSourceFile.get(subClass);
assert sourceFileName != null;
if (r != null) {
final StringCache.S sourceFileName = classToSourceFile.get(subClass);
if (r.isLocal) {
affectedFiles.add(sourceFileName);
@@ -643,7 +718,12 @@ public class Mappings {
final Collection<StringCache.S> propagated = u.propagateFieldAccess(f.name, subClass);
u.affectFieldUsages(f, propagated, f.createUsage(subClass), affectedUsages, dependants);
dependants.addAll(fileToFileDependency.foxyGet(classToSourceFile.get(subClass)));
final Collection<StringCache.S> deps = fileToFileDependency.foxyGet(sourceFileName);
if (deps != null) {
dependants.addAll(deps);
}
}
}
}
@@ -651,8 +731,8 @@ public class Mappings {
final Collection<Pair<FieldRepr, ClassRepr>> overriden = u.findOverridenFields(f, it);
for (Pair<FieldRepr, ClassRepr> p : overriden) {
final FieldRepr ff = p.fst;
final ClassRepr cc = p.snd;
final FieldRepr ff = p.first;
final ClassRepr cc = p.second;
final boolean ffPrivate = (ff.access & Opcodes.ACC_PRIVATE) > 0;
final boolean ffProtected = (ff.access & Opcodes.ACC_PROTECTED) > 0;
@@ -703,8 +783,8 @@ public class Mappings {
}
for (Pair<FieldRepr, Difference> f : diff.fields().changed()) {
final Difference d = f.snd;
final FieldRepr field = f.fst;
final Difference d = f.second;
final FieldRepr field = f.first;
if ((field.access & mask) == mask) {
if ((d.base() & Difference.ACCESS) > 0 || (d.base() & Difference.VALUE) > 0) {
@@ -808,11 +888,11 @@ public class Mappings {
return true;
}
public void integrate (final Mappings delta, final Collection<String> removed) {
integrate(delta, cache(removed));
public void integrate(final Mappings delta, final Collection<File> compiled, final Collection<String> removed) {
integrate(delta, cacheFiles(compiled), cachePaths(removed));
}
public void integrate(final Mappings delta, final Set<StringCache.S> removed) {
public void integrate(final Mappings delta, final Collection<StringCache.S> compiled, final Set<StringCache.S> removed) {
if (removed != null) {
for (StringCache.S file : removed) {
final Set<ClassRepr> classes = (Set<ClassRepr>)sourceFileToClasses.foxyGet(file);
@@ -836,7 +916,26 @@ public class Mappings {
sourceFileToUsages.putAll(delta.sourceFileToUsages);
sourceFileToAnnotationUsages.putAll(delta.sourceFileToAnnotationUsages);
classToSourceFile.putAll(delta.classToSourceFile);
fileToFileDependency.putAll(delta.fileToFileDependency);
for (StringCache.S file : delta.fileToFileDependency.keySet()) {
final Collection<StringCache.S> now = delta.fileToFileDependency.foxyGet(file);
final Collection<StringCache.S> past = fileToFileDependency.foxyGet(file);
if (past == null) {
fileToFileDependency.put(file, now);
}
else {
final Collection<StringCache.S> removeSet = new HashSet<StringCache.S>(compiled);
removeSet.removeAll(now);
past.addAll(now);
past.removeAll(removeSet);
fileToFileDependency.remove(file);
fileToFileDependency.put(file, past);
}
}
}
private void updateFormToClass(final StringCache.S formName, final StringCache.S className) {
@@ -874,7 +973,7 @@ public class Mappings {
}
}
private void updateClassToSource(final StringCache.S className, final StringCache.S sourceName) {
private void updateClassToSource(@NotNull final StringCache.S className, @NotNull final StringCache.S sourceName) {
classToSourceFile.put(className, sourceName);
final Set<StringCache.S> waiting = (Set<StringCache.S>)waitingForResolve.foxyGet(className);
@@ -895,14 +994,14 @@ public class Mappings {
}
public void associate(final String classFileName, final Callbacks.SourceFileNameLookup sourceFileName, final ClassReader cr) {
final StringCache.S classFileNameS = StringCache.get(project.getRelativePath(classFileName));
final StringCache.S classFileNameS = StringCache.get(classFileName);
final Pair<ClassRepr, Pair<UsageRepr.Cluster, Set<UsageRepr.Usage>>> result = ClassfileAnalyzer.analyze(classFileNameS, cr);
final ClassRepr repr = result.fst;
final UsageRepr.Cluster localUsages = result.snd.fst;
final Set<UsageRepr.Usage> localAnnotationUsages = result.snd.snd;
final ClassRepr repr = result.first;
final UsageRepr.Cluster localUsages = result.second.first;
final Set<UsageRepr.Usage> localAnnotationUsages = result.second.second;
final StringCache.S sourceFileNameS =
StringCache.get(project.getRelativePath(sourceFileName.get(repr == null ? null : repr.getSourceFileName().value)));
final String srcFileName = sourceFileName.get(repr == null ? null : repr.getSourceFileName().value);
final StringCache.S sourceFileNameS = StringCache.get(srcFileName);
for (UsageRepr.Usage u : localUsages.getUsages()) {
updateDependency(sourceFileNameS, u.getOwner());
@@ -931,22 +1030,22 @@ public class Mappings {
final String sourceFileName) {
final StringCache.S sourceFileNameS = StringCache.get(sourceFileName);
updateSourceToUsages(sourceFileNameS, usages.fst);
sourceFileToAnnotationUsages.put(sourceFileNameS, usages.snd);
updateSourceToUsages(sourceFileNameS, usages.first);
sourceFileToAnnotationUsages.put(sourceFileNameS, usages.second);
for (Pair<ClassRepr, Set<StringCache.S>> c : classes) {
final ClassRepr r = c.fst;
final Set<StringCache.S> s = c.snd;
final ClassRepr r = c.first;
final Set<StringCache.S> s = c.second;
updateClassToSource(r.name, sourceFileNameS);
classToSubclasses.put(r.name, s);
sourceFileToClasses.put(sourceFileNameS, r);
}
for (UsageRepr.Usage u : usages.fst.getUsages()) {
for (UsageRepr.Usage u : usages.first.getUsages()) {
updateDependency(sourceFileNameS, u.getOwner());
}
for (UsageRepr.Usage u : usages.snd) {
for (UsageRepr.Usage u : usages.second) {
updateDependency(sourceFileNameS, u.getOwner());
}
}
@@ -957,12 +1056,6 @@ public class Mappings {
};
}
private final ProjectWrapper project;
public Mappings(final ProjectWrapper p) {
project = p;
}
public Set<ClassRepr> getClasses(final StringCache.S sourceFileName) {
return (Set<ClassRepr>)sourceFileToClasses.foxyGet(sourceFileName);
}
@@ -998,6 +1091,9 @@ public class Mappings {
public StringCache.S getJavaByForm(final StringCache.S formFileName) {
final StringCache.S classFileName = formToClass.get(formFileName);
assert classFileName != null;
return classToSourceFile.get(classFileName);
}
@@ -1016,34 +1112,4 @@ public class Mappings {
return null;
}
public void print() {
try {
final BufferedWriter w = new BufferedWriter(new FileWriter("dep.txt"));
for (StringCache.S key : fileToFileDependency.keySet()) {
final Set<StringCache.S> value = (Set<StringCache.S>)fileToFileDependency.foxyGet(key);
w.write(key.value + " -->");
w.newLine();
if (value != null) {
for (StringCache.S s : value) {
if (s == null) {
w.write(" <null>");
}
else {
w.write(" " + s.value);
}
w.newLine();
}
}
}
w.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,149 @@
package org.jetbrains.ether.dependencyView;
import org.jetbrains.ether.RW;
import org.objectweb.asm.Type;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 01.02.11
* Time: 5:03
* To change this template use File | Settings | File Templates.
*/
public class MethodRepr extends ProtoMember {
private static TypeRepr.AbstractType[] dummyAbstractType = new TypeRepr.AbstractType[0];
public final TypeRepr.AbstractType[] argumentTypes;
public final Set<TypeRepr.AbstractType> exceptions;
public abstract class Diff extends Difference {
public abstract Specifier<TypeRepr.AbstractType> exceptions();
public abstract boolean defaultAdded();
public abstract boolean defaultRemoved();
}
@Override
public Difference difference(final Proto past) {
final Difference diff = super.difference(past);
final Difference.Specifier<TypeRepr.AbstractType> excs = Difference.make(((MethodRepr)past).exceptions, exceptions);
return new Diff() {
@Override
public int addedModifiers() {
return diff.addedModifiers();
}
@Override
public int removedModifiers() {
return diff.removedModifiers();
}
@Override
public boolean no() {
return base() == NONE && !defaultAdded() && !defaultRemoved() && excs.unchanged();
}
@Override
public boolean defaultAdded() {
return hasValue() && !((MethodRepr)past).hasValue();
}
@Override
public boolean defaultRemoved() {
return !hasValue() && ((MethodRepr)past).hasValue();
}
@Override
public Specifier<TypeRepr.AbstractType> exceptions() {
return excs;
}
@Override
public int base() {
return diff.base();
}
@Override
public boolean packageLocalOn() {
return diff.packageLocalOn();
}
};
}
public void updateClassUsages(final Set<UsageRepr.Usage> s) {
type.updateClassUsages(s);
for (int i = 0; i < argumentTypes.length; i++) {
argumentTypes[i].updateClassUsages(s);
}
if (exceptions != null) {
for (TypeRepr.AbstractType typ : exceptions) {
typ.updateClassUsages(s);
}
}
}
public MethodRepr(final int a, final String n, final String s, final String d, final String[] e, final Object value) {
super(a, s, StringCache.get(n), TypeRepr.getType(Type.getReturnType(d)), value);
exceptions = (Set<TypeRepr.AbstractType>)TypeRepr.createClassType(e, new HashSet<TypeRepr.AbstractType>());
argumentTypes = TypeRepr.getType(Type.getArgumentTypes(d));
}
public MethodRepr(final BufferedReader r) {
super(r);
argumentTypes = RW.readMany(r, TypeRepr.reader, new ArrayList<TypeRepr.AbstractType>()).toArray(dummyAbstractType);
exceptions = (Set<TypeRepr.AbstractType>)RW.readMany(r, TypeRepr.reader, new HashSet<TypeRepr.AbstractType>());
}
public void write(final BufferedWriter w) {
super.write(w);
RW.writeln(w, argumentTypes, TypeRepr.fromAbstractType);
RW.writeln(w, exceptions);
}
public static RW.Reader<MethodRepr> reader = new RW.Reader<MethodRepr>() {
public MethodRepr read(final BufferedReader r) {
return new MethodRepr(r);
}
};
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final MethodRepr that = (MethodRepr)o;
return name.equals(that.name) && type.equals(that.type) && Arrays.equals(argumentTypes, that.argumentTypes);
}
@Override
public int hashCode() {
return 31 * (31 * Arrays.hashCode(argumentTypes) + type.hashCode()) + name.hashCode();
}
public UsageRepr.Usage createUsage(final StringCache.S owner) {
final StringBuilder buf = new StringBuilder();
buf.append("(");
for (TypeRepr.AbstractType t : argumentTypes) {
buf.append(t.getDescr());
}
buf.append(")");
buf.append(type.getDescr());
return UsageRepr.createMethodUsage(name.value, owner.value, buf.toString());
}
}
@@ -0,0 +1,281 @@
package org.jetbrains.ether.dependencyView;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 02.04.11
* Time: 17:12
* To change this template use File | Settings | File Templates.
*/
public class PackageNameSelector {
String buffer = null;
int index = 0;
BufferedReader reader = null;
char saved;
boolean isSaved = false;
private void read() {
try {
buffer = reader.readLine();
index = 0;
}
catch (IOException e) {
e.printStackTrace();
}
}
private char get() {
if (buffer == null) {
return 0;
}
else if (index == buffer.length()) {
read();
return '\r';
}
final char c = buffer.charAt(index++);
if (c == 0) {
return ' ';
}
return c;
}
private char symbol() {
if (isSaved) {
isSaved = false;
return saved;
}
final char c = get();
switch (c) {
case '"': {
loop:
while (true) {
switch (get()) {
case 0:
return 0;
case '"':
case '\r':
break loop;
case '\\':
switch (get()) {
case 0:
return 0;
case '\r':
break loop;
}
}
}
return ' ';
}
case '\'': {
loop:
while (true) {
switch (get()) {
case 0:
return 0;
case '\'':
case '\r':
break loop;
case '\\':
switch (get()) {
case 0:
return 0;
case '\r':
break loop;
}
}
}
return ' ';
}
case '/': {
final char d = get();
if (d == '/') {
loop:
while (true) {
switch (get()) {
case 0:
return 0;
case '\r':
break loop;
}
}
return ' ';
}
else if (d == '*') {
loop:
while (true) {
switch (get()) {
case 0:
return 0;
case '*':
inner:
while (true) {
switch (get()) {
case 0:
return 0;
case '/':
break loop;
case '*':
continue;
default:
break inner;
}
}
}
}
return ' ';
}
else {
saved = d;
isSaved = true;
return c;
}
}
default: {
return c;
}
}
}
private void open(final String fileName) {
try {
reader = new BufferedReader(new FileReader(new File(fileName)));
read();
}
catch (IOException e) {
e.printStackTrace();
}
}
private void close() {
try {
if (reader != null) {
reader.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
private String parse() {
final StringBuilder b = new StringBuilder();
int state = 0;
while (true) {
final char c = symbol();
switch (c) {
case 0: {
return "";
}
default: {
switch (state) {
case 0: // Initial state
if (Character.isLetter(c)) {
b.append(c);
state = 1;
}
break;
case 1: // Identifier
if (Character.isLetter(c)) {
b.append(c);
}
else if (Character.isWhitespace(c)) {
final String ident = b.toString();
b.setLength(0);
if (ident.equals("package")) {
state = 2;
}
else if (ident.equals("import")) {
return "";
}
}
else {
state = 0;
}
break;
case 2: // Post "package<whitespace>
if (Character.isWhitespace(c)) {
}
else if (c == '.') {
b.append(File.separatorChar);
}
else if (c == ';') {
return b.toString();
}
else {
b.append(c);
}
}
}
}
}
}
public String get(final String fileName) {
open(fileName);
final String result = parse();
close();
return result;
}
//
// final private static String whiteSpacePattern = "(/\\*.*?\\*/|//[^\\r\\n\\f\\x0B]*)";
// final private static String stringLiteralPattern = "(\"([^\\\\\"]|\\\\.)*\")";
// final private static String charLiteralPattern = "('([^\\\\']|\\\\.)*')";
// final private static Pattern skipPattern = Pattern.compile(whiteSpacePattern + "|" + stringLiteralPattern + "|" + charLiteralPattern, Pattern.DOTALL);
// final private static Pattern packagePattern = Pattern.compile("\\bpackage\\s+([^;]+);");
// final private static Pattern spacePattern = Pattern.compile("\\s+");
// final private static Pattern dotPattern = Pattern.compile("\\.");
//
// public static String get (final String fileName) throws Exception {
// //try {
// final FileChannel channel = new FileInputStream(fileName).getChannel();
//
// final Matcher skipMatcher = skipPattern.matcher(Charset.forName("ISO-8859-1").newDecoder().decode(channel.map(FileChannel.MapMode.READ_ONLY, 0, (int) channel.size())));
// final String cleared = skipMatcher.replaceAll(" ");
//
// System.out.println(cleared);
//
// final Matcher selecting = packagePattern.matcher(cleared);
//
// if (selecting.find()) {
// final String qualifiedName = selecting.group(1);
// final Matcher spaceRemover = spacePattern.matcher(qualifiedName);
// final String spaceRemoved = spaceRemover.replaceAll("");
// final Matcher dotReplacer = dotPattern.matcher(spaceRemoved);
//
// return dotReplacer.replaceAll("/");
// } else {
// return null;
// }
// //} catch (IOException e) {
// // e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
//
// // return null;
// //}
// }
}
@@ -0,0 +1,85 @@
package org.jetbrains.ether.dependencyView;
import groovyjarjarasm.asm.Opcodes;
import org.jetbrains.ether.RW;
import java.io.BufferedReader;
import java.io.BufferedWriter;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 01.03.11
* Time: 17:57
* To change this template use File | Settings | File Templates.
*/
public abstract class Proto implements RW.Writable {
public final int access;
public final StringCache.S signature;
public final StringCache.S name;
protected Proto(final int access, final String signature, final StringCache.S name) {
this.access = access;
this.signature = StringCache.get(signature != null ? signature : "");
this.name = name;
}
protected Proto(final BufferedReader r) {
access = RW.readInt(r);
signature = StringCache.get(RW.readString(r));
name = StringCache.get(RW.readString(r));
}
public void write(final BufferedWriter w) {
RW.writeln(w, Integer.toString(access));
RW.writeln(w, signature.value);
RW.writeln(w, name.value);
}
public Difference difference(final Proto past) {
int diff = Difference.NONE;
if (past.access != access) {
diff |= Difference.ACCESS;
}
if (!past.signature.equals(signature)) {
diff |= Difference.SIGNATURE;
}
final int base = diff;
return new Difference() {
@Override
public int base() {
return base;
}
@Override
public boolean no() {
return base == NONE;
}
@Override
public int addedModifiers() {
return ~past.access & access;
}
@Override
public int removedModifiers() {
return ~access & past.access;
}
@Override
public boolean packageLocalOn() {
return ((past.access & Opcodes.ACC_PRIVATE) != 0 ||
(past.access & Opcodes.ACC_PUBLIC) != 0 ||
(past.access & Opcodes.ACC_PROTECTED) != 0)
&&
((access & Opcodes.ACC_PRIVATE) == 0 && (access & Opcodes.ACC_PROTECTED) == 0 && (access & Opcodes.ACC_PUBLIC) == 0);
}
};
}
}
@@ -0,0 +1,147 @@
package org.jetbrains.ether.dependencyView;
import org.jetbrains.ether.RW;
import java.io.BufferedReader;
import java.io.BufferedWriter;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 07.03.11
* Time: 19:54
* To change this template use File | Settings | File Templates.
*/
public abstract class ProtoMember extends Proto {
public final TypeRepr.AbstractType type;
public final Object value;
public boolean hasValue() {
return value != null;
}
protected ProtoMember(final int access,
final String signature,
final StringCache.S name,
final TypeRepr.AbstractType t,
final Object value) {
super(access, signature, name);
this.type = t;
this.value = value;
}
private static Object readTyped(final BufferedReader r, final String tag) {
if (tag.equals("string")) {
return RW.readEncodedString(r);
}
if (tag.equals("none")) {
return null;
}
final String val = RW.readString(r);
if (tag.equals("integer")) return Integer.parseInt(val);
if (tag.equals("long")) return Long.parseLong(val);
if (tag.equals("float")) return Float.parseFloat(val);
if (tag.equals("double")) return Double.parseDouble(val);
return null;
}
protected ProtoMember(final BufferedReader r) {
super(r);
type = TypeRepr.reader.read(r);
value = readTyped(r, RW.readString(r));
}
public void write(final BufferedWriter w) {
super.write(w);
type.write(w);
if (value instanceof String) {
RW.writeln(w, "string");
RW.writeEncodedString(w, (String)value);
}
else if (value instanceof Integer) {
RW.writeln(w, "integer");
RW.writeln(w, value.toString());
}
else if (value instanceof Long) {
RW.writeln(w, "long");
RW.writeln(w, value.toString());
}
else if (value instanceof Float) {
RW.writeln(w, "float");
RW.writeln(w, value.toString());
}
else if (value instanceof Double) {
RW.writeln(w, "double");
RW.writeln(w, value.toString());
}
else {
RW.writeln(w, "none");
}
}
public Difference difference(final Proto past) {
final ProtoMember m = (ProtoMember)past;
final Difference diff = super.difference(past);
int base = diff.base();
if (!m.type.equals(type)) {
base |= Difference.TYPE;
}
switch ((value == null ? 0 : 1) + (m.value == null ? 0 : 2)) {
case 3:
if (!value.equals(m.value)) {
base |= Difference.VALUE;
}
break;
case 2:
base |= Difference.VALUE;
break;
case 1:
base |= Difference.VALUE;
break;
case 0:
break;
}
final int newBase = base;
return new Difference() {
@Override
public int base() {
return newBase;
}
@Override
public boolean no() {
return newBase == NONE && diff.no();
}
@Override
public int addedModifiers() {
return diff.addedModifiers();
}
@Override
public int removedModifiers() {
return diff.removedModifiers();
}
@Override
public boolean packageLocalOn() {
return diff.packageLocalOn();
}
};
}
}
@@ -0,0 +1,115 @@
package org.jetbrains.ether.dependencyView;
import org.jetbrains.ether.RW;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 14.02.11
* Time: 2:03
* To change this template use File | Settings | File Templates.
*/
public class StringCache {
public static class S implements Comparable<S>, RW.Writable {
public final int index;
public final String value;
private S(final int i, final String v) {
index = i;
value = v;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
S s = (S)o;
if (index != s.index) return false;
return true;
}
@Override
public int hashCode() {
return index;
}
public int compareTo(S o) {
return index - o.index;
}
public void write(BufferedWriter w) {
RW.writeln(w, value);
}
public static final RW.Reader<S> reader = new RW.Reader<S>() {
public S read(final BufferedReader r) {
final String s = RW.readString(r);
return StringCache.get(s);
}
};
public String toString() {
return value;
}
}
private static final Map<String, S> map = new HashMap<String, S>();
private static int index = 0;
public static S get(final String s) {
// if (s == null)
// return null;
//
S r = map.get(s);
if (r == null) {
r = new S(index++, s);
map.put(s, r);
}
return r;
}
public static S[] get(final String[] s) {
if (s == null) {
return null;
}
final S[] r = new S[s.length];
for (int i = 0; i < r.length; i++) {
r[i] = get(s[i]);
}
return r;
}
public static RW.ToWritable<S> fromS = new RW.ToWritable<S>() {
public RW.Writable convert(S x) {
return RW.fromString.convert(x.value);
}
};
public static RW.Reader<S> reader = new RW.Reader<S>() {
public S read(final BufferedReader r) {
try {
return get(r.readLine());
}
catch (IOException e) {
e.printStackTrace();
return null;
}
}
};
}
@@ -0,0 +1,317 @@
package org.jetbrains.ether.dependencyView;
import org.jetbrains.ether.RW;
import org.objectweb.asm.Type;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.util.*;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 14.02.11
* Time: 3:54
* To change this template use File | Settings | File Templates.
*/
public class TypeRepr {
public static abstract class AbstractType implements RW.Writable {
public abstract void updateClassUsages(Set<UsageRepr.Usage> s);
public abstract String getDescr();
}
public static class PrimitiveType extends AbstractType {
public final StringCache.S type;
@Override
public String getDescr() {
return type.value;
}
@Override
public void updateClassUsages(Set<UsageRepr.Usage> s) {
}
public void write(final BufferedWriter w) {
RW.writeln(w, "primitive");
RW.writeln(w, type.value);
}
PrimitiveType(final String type) {
this.type = StringCache.get(type);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final PrimitiveType that = (PrimitiveType)o;
return type.equals(that.type);
}
@Override
public int hashCode() {
return type.hashCode();
}
}
public static class ArrayType extends AbstractType {
public final AbstractType elementType;
public AbstractType getDeepElementType() {
AbstractType current = this;
while (current instanceof ArrayType) {
current = ((ArrayType)current).elementType;
}
return current;
}
@Override
public String getDescr() {
return "[" + elementType.getDescr();
}
@Override
public void updateClassUsages(Set<UsageRepr.Usage> s) {
elementType.updateClassUsages(s);
}
ArrayType(final AbstractType elementType) {
this.elementType = elementType;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final ArrayType arrayType = (ArrayType)o;
return elementType.equals(arrayType.elementType);
}
@Override
public int hashCode() {
return elementType.hashCode();
}
public void write(BufferedWriter w) {
RW.writeln(w, "array");
elementType.write(w);
}
}
public static class ClassType extends AbstractType {
public final StringCache.S className;
public final AbstractType[] typeArgs;
@Override
public String getDescr() {
return "L" + className.value + ";";
}
@Override
public void updateClassUsages(Set<UsageRepr.Usage> s) {
s.add(UsageRepr.createClassUsage(className));
}
ClassType(final BufferedReader r) {
className = StringCache.get(RW.readString(r));
final Collection<AbstractType> args = RW.readMany(r, reader, new LinkedList<AbstractType>());
typeArgs = args.toArray(new AbstractType[args.size()]);
}
ClassType(final String className) {
this.className = StringCache.get(className);
typeArgs = new AbstractType[0];
}
ClassType(final StringCache.S className) {
this.className = className;
typeArgs = new AbstractType[0];
}
ClassType(final String className, final AbstractType[] typeArgs) {
this.className = StringCache.get(className);
this.typeArgs = typeArgs;
}
ClassType(final StringCache.S className, final AbstractType[] typeArgs) {
this.className = className;
this.typeArgs = typeArgs;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final ClassType classType = (ClassType)o;
if (className != null ? !className.equals(classType.className) : classType.className != null) return false;
if (!Arrays.equals(typeArgs, classType.typeArgs)) return false;
return true;
}
@Override
public int hashCode() {
int result = className != null ? className.hashCode() : 0;
result = 31 * result + (typeArgs != null ? Arrays.hashCode(typeArgs) : 0);
return result;
}
public void write(BufferedWriter w) {
RW.writeln(w, "class");
RW.writeln(w, className.value);
RW.writeln(w, typeArgs);
}
}
public static ClassType createClassType(final String s) {
return (ClassType)getType(new ClassType(s));
}
public static ClassType createClassType(final StringCache.S s) {
return (ClassType)getType(new ClassType(s));
}
public static ClassType[] createClassType(final String[] s) {
if (s == null) {
return null;
}
final ClassType[] types = new ClassType[s.length];
for (int i = 0; i < types.length; i++) {
types[i] = createClassType(s[i]);
}
return types;
}
public static Collection<AbstractType> createClassType(final String[] s, final Collection<AbstractType> acc) {
if (s != null) {
for (String ss : s) {
acc.add(createClassType(ss));
}
}
return acc;
}
public static Collection<AbstractType> createClassType(final Collection<String> s, final Collection<AbstractType> acc) {
if (s != null) {
for (String ss : s) {
acc.add(createClassType(ss));
}
}
return acc;
}
private static final Map<AbstractType, AbstractType> map = new HashMap<AbstractType, AbstractType>();
private static AbstractType getType(final AbstractType t) {
final AbstractType r = map.get(t);
if (r != null) {
return r;
}
map.put(t, t);
return t;
}
public static AbstractType getType(final String descr) {
final Type t = Type.getType(descr);
switch (t.getSort()) {
case Type.OBJECT:
return getType(new ClassType(t.getClassName()));
case Type.ARRAY:
return getType(new ArrayType(getType(t.getElementType())));
default:
return getType(new PrimitiveType(descr));
}
}
public static AbstractType getType(final Type t) {
return getType(t.getDescriptor());
}
public static AbstractType[] getType(final Type[] t) {
final AbstractType[] r = new AbstractType[t.length];
for (int i = 0; i < r.length; i++) {
r[i] = getType(t[i]);
}
return r;
}
public static AbstractType[] getType(final String[] t) {
if (t == null) {
return null;
}
final AbstractType[] types = new AbstractType[t.length];
for (int i = 0; i < types.length; i++) {
types[i] = getType(Type.getType(t[i]));
}
return types;
}
public static RW.Reader<AbstractType> reader = new RW.Reader<AbstractType>() {
public AbstractType read(final BufferedReader r) {
AbstractType elementType = null;
int level = 0;
while (true) {
final String tag = RW.readString(r);
if (tag.equals("primitive")) {
elementType = getType(new PrimitiveType(RW.readString(r)));
break;
}
if (tag.equals("class")) {
elementType = getType(new ClassType(r));
break;
}
if (tag.equals("array")) {
level++;
}
}
for (int i = 0; i < level; i++) {
elementType = getType(new ArrayType(elementType));
}
return elementType;
}
};
public static RW.ToWritable<AbstractType> fromAbstractType = new RW.ToWritable<AbstractType>() {
public RW.Writable convert(final AbstractType x) {
return new RW.Writable() {
public void write(final BufferedWriter w) {
x.write(w);
}
};
}
};
}
@@ -0,0 +1,522 @@
package org.jetbrains.ether.dependencyView;
import org.jetbrains.ether.RW;
import org.objectweb.asm.Type;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.lang.annotation.ElementType;
import java.util.*;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 14.02.11
* Time: 5:11
* To change this template use File | Settings | File Templates.
*/
public class UsageRepr {
private final static TypeRepr.AbstractType[] dummyAbstractType = new TypeRepr.AbstractType[0];
private final static Map<Usage, Usage> map = new HashMap<Usage, Usage>();
private static Usage getUsage(final Usage u) {
final Usage r = map.get(u);
if (r == null) {
map.put(u, u);
return u;
}
return r;
}
public static class Cluster implements RW.Writable {
final Set<Usage> usages = new HashSet<Usage>();
final Map<Usage, Set<StringCache.S>> residentialMap = new HashMap<Usage, Set<StringCache.S>>();
public Cluster() {
}
public Cluster(final BufferedReader r) {
final int size = RW.readInt(r);
for (int i = 0; i < size; i++) {
final Usage u = reader.read(r);
final Set<StringCache.S> s = (Set<StringCache.S>)RW.readMany(r, StringCache.reader, new HashSet<StringCache.S>());
usages.add(u);
residentialMap.put(u, s);
}
}
public void write(final BufferedWriter w) {
RW.writeln(w, Integer.toString(usages.size()));
for (Usage u : usages) {
u.write(w);
RW.writeln(w, residentialMap.get(u));
}
}
public void addUsage(final String residence, final Usage usage) {
final StringCache.S r = StringCache.get(residence);
Set<StringCache.S> s = residentialMap.get(usage);
if (s == null) {
s = new HashSet<StringCache.S>();
residentialMap.put(usage, s);
}
s.add(r);
usages.add(usage);
}
public Set<Usage> getUsages() {
return usages;
}
public Set<StringCache.S> getResidence(final Usage usage) {
return residentialMap.get(usage);
}
public void updateCluster(final Cluster c) {
usages.addAll(c.getUsages());
for (Map.Entry<Usage, Set<StringCache.S>> e : c.residentialMap.entrySet()) {
final Usage u = e.getKey();
final Set<StringCache.S> v = e.getValue();
final Set<StringCache.S> s = residentialMap.get(u);
if (s == null) {
residentialMap.put(u, v);
}
else {
s.addAll(v);
}
}
}
public boolean isEmpty() {
return usages.isEmpty();
}
}
public static abstract class Usage implements RW.Writable {
public abstract StringCache.S getOwner();
}
public static abstract class FMUsage extends Usage {
public final StringCache.S name;
public final StringCache.S owner;
@Override
public StringCache.S getOwner() {
return owner;
}
protected FMUsage(final String n, final String o) {
name = StringCache.get(n);
owner = StringCache.get(o);
}
protected FMUsage(final BufferedReader r) {
name = StringCache.get(RW.readString(r));
owner = StringCache.get(RW.readString(r));
}
}
public static class FieldUsage extends FMUsage {
public final TypeRepr.AbstractType type;
private FieldUsage(final String n, final String o, final String d) {
super(n, o);
type = TypeRepr.getType(d);
}
private FieldUsage(final BufferedReader r) {
super(r);
type = TypeRepr.reader.read(r);
}
public void write(final BufferedWriter w) {
RW.writeln(w, "fieldUsage");
RW.writeln(w, name.value);
RW.writeln(w, owner.value);
type.write(w);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final FieldUsage that = (FieldUsage)o;
return type.equals(that.type) && name.equals(that.name) && owner.equals(that.owner);
}
@Override
public int hashCode() {
return 31 * (31 * type.hashCode() + (name.hashCode())) + owner.hashCode();
}
}
public static class FieldAssignUsage extends FieldUsage {
private FieldAssignUsage(final String n, final String o, final String d) {
super(n, o, d);
}
private FieldAssignUsage(final BufferedReader r) {
super(r);
}
public void write(final BufferedWriter w) {
RW.writeln(w, "fieldAssignUsage");
RW.writeln(w, name.value);
RW.writeln(w, owner.value);
type.write(w);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final FieldAssignUsage that = (FieldAssignUsage)o;
return type.equals(that.type) && name.equals(that.name) && owner.equals(that.owner);
}
@Override
public int hashCode() {
return super.hashCode() + 1;
}
}
public static class MethodUsage extends FMUsage {
public final TypeRepr.AbstractType[] argumentTypes;
public final TypeRepr.AbstractType returnType;
private MethodUsage(final String n, final String o, final String d) {
super(n, o);
argumentTypes = TypeRepr.getType(Type.getArgumentTypes(d));
returnType = TypeRepr.getType(Type.getReturnType(d));
}
private MethodUsage(final BufferedReader r) {
super(r);
argumentTypes = RW.readMany(r, TypeRepr.reader, new ArrayList<TypeRepr.AbstractType>()).toArray(dummyAbstractType);
returnType = TypeRepr.reader.read(r);
}
public void write(final BufferedWriter w) {
RW.writeln(w, "methodUsage");
RW.writeln(w, name.value);
RW.writeln(w, owner.value);
RW.writeln(w, argumentTypes, TypeRepr.fromAbstractType);
returnType.write(w);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final MethodUsage that = (MethodUsage)o;
if (!Arrays.equals(argumentTypes, that.argumentTypes)) return false;
if (returnType != null ? !returnType.equals(that.returnType) : that.returnType != null) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
if (owner != null ? !owner.equals(that.owner) : that.owner != null) return false;
return Arrays.equals(argumentTypes, that.argumentTypes) &&
returnType.equals(that.returnType) &&
name.equals(that.name) &&
owner.equals(that.owner);
}
@Override
public int hashCode() {
return ((31 * Arrays.hashCode(argumentTypes) + (returnType.hashCode())) * 31 + (name.hashCode())) * 31 + (owner.hashCode());
}
}
public static class ClassUsage extends Usage {
final StringCache.S className;
@Override
public StringCache.S getOwner() {
return className;
}
private ClassUsage(final String n) {
className = StringCache.get(n);
}
private ClassUsage(final StringCache.S n) {
className = n;
}
private ClassUsage(final BufferedReader r) {
className = StringCache.get(RW.readString(r));
}
private ClassUsage(final BufferedReader r, boolean b) {
super();
className = StringCache.get(RW.readString(r));
}
public void write(final BufferedWriter w) {
RW.writeln(w, "classUsage");
RW.writeln(w, className.value);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final ClassUsage that = (ClassUsage)o;
return className.equals(that.className);
}
@Override
public int hashCode() {
return className.hashCode();
}
}
public static class ClassExtendsUsage extends Usage {
protected final StringCache.S className;
@Override
public StringCache.S getOwner() {
return className;
}
public ClassExtendsUsage(final StringCache.S n) {
className = n;
}
public ClassExtendsUsage(final BufferedReader r) {
className = StringCache.get(RW.readString(r));
}
public void write(final BufferedWriter w) {
RW.writeln(w, "classExtendsUsage");
RW.writeln(w, className.value);
}
@Override
public int hashCode() {
return className.hashCode() + 1;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ClassExtendsUsage that = (ClassExtendsUsage)o;
if (!className.equals(that.className)) return false;
return true;
}
}
public static class ClassNewUsage extends ClassExtendsUsage {
public ClassNewUsage(StringCache.S n) {
super(n);
}
public ClassNewUsage(BufferedReader r) {
super(r);
}
public void write(final BufferedWriter w) {
RW.writeln(w, "classNewUsage");
RW.writeln(w, className.value);
}
@Override
public int hashCode() {
return className.hashCode() + 2;
}
}
public static class AnnotationUsage extends Usage {
public static final RW.Reader<ElementType> elementTypeReader = new RW.Reader<ElementType>() {
public ElementType read(final BufferedReader r) {
return ElementType.valueOf(RW.readString(r));
}
};
public static final RW.ToWritable<ElementType> elementTypeToWritable = new RW.ToWritable<ElementType>() {
public RW.Writable convert(final ElementType x) {
return new RW.Writable() {
public void write(final BufferedWriter w) {
RW.writeln(w, x.toString());
}
};
}
};
final TypeRepr.ClassType type;
final Collection<StringCache.S> usedArguments;
final Collection<ElementType> usedTargets;
public boolean satisfies(final Usage usage) {
if (usage instanceof AnnotationUsage) {
final AnnotationUsage annotationUsage = (AnnotationUsage)usage;
if (!type.equals(annotationUsage.type)) {
return false;
}
boolean argumentsSatisfy = false;
if (usedArguments != null) {
final Collection<StringCache.S> arguments = new HashSet<StringCache.S>(usedArguments);
arguments.removeAll(annotationUsage.usedArguments);
argumentsSatisfy = !arguments.isEmpty();
}
boolean targetsSatisfy = false;
if (usedTargets != null) {
final Collection<ElementType> targets = new HashSet<ElementType>(usedTargets);
targets.retainAll(annotationUsage.usedTargets);
targetsSatisfy = !targets.isEmpty();
}
return argumentsSatisfy || targetsSatisfy;
}
return false;
}
private AnnotationUsage(final TypeRepr.ClassType type,
final Collection<StringCache.S> usedArguments,
final Collection<ElementType> targets) {
this.type = type;
this.usedArguments = usedArguments;
this.usedTargets = targets;
}
private AnnotationUsage(final BufferedReader r) {
type = (TypeRepr.ClassType)TypeRepr.reader.read(r);
usedArguments = RW.readMany(r, StringCache.reader, new HashSet<StringCache.S>());
usedTargets = RW.readMany(r, elementTypeReader, new HashSet<ElementType>());
}
@Override
public StringCache.S getOwner() {
return type.className;
}
public void write(final BufferedWriter w) {
RW.writeln(w, "annotationUsage");
type.write(w);
RW.writeln(w, usedArguments);
RW.writeln(w, usedTargets, elementTypeToWritable);
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AnnotationUsage that = (AnnotationUsage)o;
if (usedArguments != null ? !usedArguments.equals(that.usedArguments) : that.usedArguments != null) return false;
if (usedTargets != null ? !usedTargets.equals(that.usedTargets) : that.usedTargets != null) return false;
if (type != null ? !type.equals(that.type) : that.type != null) return false;
return true;
}
@Override
public int hashCode() {
int result = type != null ? type.hashCode() : 0;
result = 31 * result + (usedArguments != null ? usedArguments.hashCode() : 0);
result = 31 * result + (usedTargets != null ? usedTargets.hashCode() : 0);
return result;
}
}
public static Usage createFieldUsage(final String name, final String owner, final String descr) {
return getUsage(new FieldUsage(name, owner, descr));
}
public static Usage createFieldAssignUsage(final String name, final String owner, final String descr) {
return getUsage(new FieldAssignUsage(name, owner, descr));
}
public static Usage createMethodUsage(final String name, final String owner, final String descr) {
return getUsage(new MethodUsage(name, owner, descr));
}
public static Usage createClassUsage(final String name) {
return getUsage(new ClassUsage(name));
}
public static Usage createClassUsage(final StringCache.S name) {
return getUsage(new ClassUsage(name));
}
public static Usage createClassExtendsUsage(final StringCache.S name) {
return getUsage(new ClassExtendsUsage(name));
}
public static Usage createClassNewUsage(final StringCache.S name) {
return getUsage(new ClassNewUsage(name));
}
public static Usage createAnnotationUsage(final TypeRepr.ClassType type,
final Collection<StringCache.S> usedArguments,
final Collection<ElementType> targets) {
return getUsage(new AnnotationUsage(type, usedArguments, targets));
}
public static RW.Reader<Usage> reader = new RW.Reader<Usage>() {
public Usage read(final BufferedReader r) {
final String tag = RW.readString(r);
if (tag.equals("classUsage")) {
return getUsage(new ClassUsage(r));
}
else if (tag.equals("fieldUsage")) {
return getUsage(new FieldUsage(r));
}
else if (tag.equals("fieldAssignUsage")) {
return getUsage(new FieldAssignUsage(r));
}
else if (tag.equals("methodUsage")) {
return getUsage(new MethodUsage(r));
}
else if (tag.equals("classExtendsUsage")) {
return getUsage(new ClassExtendsUsage(r));
}
else if (tag.equals("classNewUsage")) {
return getUsage(new ClassNewUsage(r));
}
else {
return getUsage(new AnnotationUsage(r));
}
}
};
public static RW.Reader<Cluster> clusterReader = new RW.Reader<Cluster>() {
@Override
public Cluster read(BufferedReader r) {
return new Cluster(r);
}
};
}
@@ -1,6 +1,5 @@
package org.jetbrains.jps;
import com.intellij.openapi.util.Key;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -12,8 +11,6 @@ import java.util.*;
* Date: 9/30/11
*/
public class ProjectPaths {
public static final Key<ProjectPaths> KEY = Key.create("_project_paths_");
@NotNull
private final Project myProject;
@Nullable
@@ -81,10 +78,16 @@ public class ProjectPaths {
if (it instanceof ModuleSourceEntry) {
final Module dep = ((ModuleSourceEntry) it).getModule();
if (!excludeMainModuleOutput && kind.isTestsIncluded()) {
classpath.add(getModuleOutputDir(dep, true));
final File out = getModuleOutputDir(dep, true);
if (out != null) {
classpath.add(out);
}
}
if (!excludeMainModuleOutput || kind.isTestsIncluded()) {
classpath.add(getModuleOutputDir(dep, false));
final File out = getModuleOutputDir(dep, false);
if (out != null) {
classpath.add(out);
}
}
}
else if (it instanceof Module) {
@@ -169,6 +172,7 @@ public class ProjectPaths {
(forTests ? myCustomModuleTestOutputDir : myCustomModuleOutputDir).put(module, outputDir);
}
@Nullable
public File getModuleOutputDir(Module module, boolean forTests) {
File customOutput = (forTests ? myCustomModuleTestOutputDir : myCustomModuleOutputDir).get(module);
if (customOutput != null) {
+137 -139
View File
@@ -18,159 +18,157 @@ import java.util.regex.Pattern;
public class DirectoryScanner {
public static class Result {
final Set<ProjectWrapper.FileWrapper> myFiles;
long myLatest;
long myEarliest;
public static class Result {
final Set<ProjectWrapper.FileWrapper> myFiles;
long myLatest;
long myEarliest;
public Result () {
myFiles = new HashSet<ProjectWrapper.FileWrapper> ();
myLatest = 0;
myEarliest = Long.MAX_VALUE;
}
public void update (final ProjectWrapper.FileWrapper w) {
final long t = w.getStamp ();
if (t > myLatest)
myLatest = t;
if (t< myEarliest)
myEarliest = t;
myFiles.add(w);
}
public long getEarliest () {
return myEarliest;
}
public long getLatest () {
return myLatest;
}
public Set<ProjectWrapper.FileWrapper> getFiles () {
return myFiles;
}
public Result() {
myFiles = new HashSet<ProjectWrapper.FileWrapper>();
myLatest = 0;
myEarliest = Long.MAX_VALUE;
}
private static class Crawler {
final Result myResult;
final FileFilter myFilter;
final ProjectWrapper myProjectWrapper;
public void update(final ProjectWrapper.FileWrapper w) {
final long t = w.getStamp();
public Crawler (final FileFilter ff, final ProjectWrapper pw) {
myResult = new Result();
myFilter = ff;
myProjectWrapper = pw;
}
if (t > myLatest) myLatest = t;
public Result getResult () {
return myResult;
}
if (t < myEarliest) myEarliest = t;
public void run(File root) {
if (root.exists()) {
final File[] files = root.listFiles(myFilter);
for (int i = 0; i < files.length; i++) {
myResult.update (myProjectWrapper.new FileWrapper(files[i]));
}
final File[] subdirs = root.listFiles(myDirectoryFilter);
for (int i = 0; i < subdirs.length; i++) {
run(subdirs[i]);
}
}
}
myFiles.add(w);
}
private static FileFilter myDirectoryFilter = new FileFilter() {
public long getEarliest() {
return myEarliest;
}
public long getLatest() {
return myLatest;
}
public Set<ProjectWrapper.FileWrapper> getFiles() {
return myFiles;
}
}
private static class Crawler {
final Result myResult;
final FileFilter myFilter;
final ProjectWrapper myProjectWrapper;
public Crawler(final FileFilter ff, final ProjectWrapper pw) {
myResult = new Result();
myFilter = ff;
myProjectWrapper = pw;
}
public Result getResult() {
return myResult;
}
public void run(File root) {
if (root.exists()) {
final File[] files = root.listFiles(myFilter);
for (int i = 0; i < files.length; i++) {
myResult.update(myProjectWrapper.new FileWrapper(files[i]));
}
final File[] subdirs = root.listFiles(myDirectoryFilter);
for (int i = 0; i < subdirs.length; i++) {
run(subdirs[i]);
}
}
}
}
private static FileFilter myDirectoryFilter = new FileFilter() {
public boolean accept(File f) {
final String name = f.getName();
return f.isDirectory() && !name.equals(".") && !name.equals("..");
}
};
private static FileFilter myTrueFilter = new FileFilter() {
public boolean accept(File s) {
return s.isFile();
}
};
private static FileFilter createFilter(final Collection<String> excludes) {
if (excludes == null) {
return myTrueFilter;
}
StringBuilder buf = new StringBuilder();
for (String exclude : excludes) {
StringBuilder alternative = new StringBuilder();
if (exclude != null) {
for (int i = 0; i < exclude.length(); i++) {
final char c = exclude.charAt(i);
switch (c) {
case '.':
case '\\':
case '*':
case '^':
case '$':
case '[':
case '(':
case '|':
alternative.append("\\");
alternative.append(c);
break;
case '?':
alternative.append(".");
break;
default:
alternative.append(c);
}
}
}
if (alternative.length() > 0) {
alternative.append(".*");
if (buf.length() > 0) buf.append("|");
buf.append("(");
buf.append(alternative);
buf.append(')');
}
}
if (buf.length() > 0) {
final Pattern patt = Pattern.compile(buf.toString());
return new FileFilter() {
public boolean accept(File f) {
final String name = f.getName();
final Matcher m = patt.matcher(f.getAbsolutePath());
final boolean ok = !m.matches();
return f.isDirectory() && !name.equals(".") && !name.equals("..");
return ok && f.isFile();
}
};
private static FileFilter myTrueFilter = new FileFilter() {
public boolean accept(File s) {
return s.isFile();
}
};
private static FileFilter createFilter(final Collection<String> excludes) {
if (excludes == null) {
return myTrueFilter;
}
StringBuilder buf = new StringBuilder();
for (String exclude : excludes) {
StringBuilder alternative = new StringBuilder();
if (exclude != null) {
for (int i = 0; i < exclude.length(); i++) {
final char c = exclude.charAt(i);
switch (c) {
case '.':
case '\\':
case '*':
case '^':
case '$':
case '[':
case '(':
case '|':
alternative.append("\\");
alternative.append(c);
break;
case '?':
alternative.append(".");
break;
default:
alternative.append(c);
}
}
}
if (alternative.length() > 0) {
alternative.append(".*");
if (buf.length() > 0)
buf.append("|");
buf.append("(");
buf.append(alternative);
buf.append(')');
}
}
if (buf.length() > 0) {
final Pattern patt = Pattern.compile(buf.toString());
return new FileFilter() {
public boolean accept(File f) {
final Matcher m = patt.matcher(f.getAbsolutePath());
final boolean ok = !m.matches();
return ok && f.isFile();
}
};
}
return myTrueFilter;
};
}
public static Result getFiles(final Set<String> roots, final Set<String> excludes, final ProjectWrapper pw) {
final Crawler cw = new Crawler(createFilter(excludes), pw);
return myTrueFilter;
}
for (String root : roots)
cw.run(new File(pw.getAbsolutePath(root)));
public static Result getFiles(final Set<String> roots, final Set<String> excludes, final ProjectWrapper pw) {
final Crawler cw = new Crawler(createFilter(excludes), pw);
return cw.getResult();
for (String root : roots) {
cw.run(new File(root));
}
return cw.getResult();
}
}
+55 -56
View File
@@ -1,6 +1,5 @@
package org.jetbrains.ether;
import java.io.BufferedWriter;
import java.io.PrintStream;
/**
@@ -11,69 +10,69 @@ import java.io.PrintStream;
* To change this template use File | Settings | File Templates.
*/
public class DotPrinter {
private final PrintStream stream;
private final PrintStream stream;
public DotPrinter(final PrintStream stream) {
this.stream = stream;
public DotPrinter(final PrintStream stream) {
this.stream = stream;
}
private static String escape(final String s) {
final StringBuilder b = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
final char c = s.charAt(i);
if (c == '_' || Character.isDigit(c) || Character.isLetter(c)) {
b.append(c);
}
else if (c == '-') {
b.append('_');
}
else {
b.append(Character.getNumericValue(c));
}
}
private static String escape(final String s) {
final StringBuilder b = new StringBuilder();
return b.toString();
}
for (int i = 0; i < s.length(); i++) {
final char c = s.charAt(i);
public static void header(final PrintStream s) {
if (s != null) s.println("digraph X {");
}
if (c == '_' || Character.isDigit(c) || Character.isLetter(c)) {
b.append(c);
} else if (c == '-') {
b.append('_');
} else {
b.append(Character.getNumericValue(c));
}
}
public void header() {
header(stream);
}
return b.toString();
public static void footer(final PrintStream s) {
if (s != null) s.println("}");
}
public void footer() {
footer(stream);
}
public static void node(final PrintStream s, String n) {
if (s != null) {
n = escape(n);
s.println(" " + n + "[label=\"" + n + "\"];");
}
}
public static void header(final PrintStream s) {
if (s != null)
s.println("digraph X {");
public void node(final String n) {
node(stream, n);
}
public static void edge(final PrintStream s, String b, String e) {
if (s != null) {
b = escape(b);
e = escape(e);
s.println(" " + b + " -> " + e + ";");
}
}
public void header() {
header(stream);
}
public static void footer(final PrintStream s) {
if (s != null)
s.println("}");
}
public void footer() {
footer(stream);
}
public static void node(final PrintStream s, String n) {
if (s != null) {
n = escape(n);
s.println(" " + n + "[label=\"" + n + "\"];");
}
}
public void node(final String n) {
node(stream, n);
}
public static void edge(final PrintStream s, String b, String e) {
if (s != null) {
b = escape(b);
e = escape(e);
s.println(" " + b + " -> " + e + ";");
}
}
public void edge(final String b, final String e) {
edge(stream, b, e);
}
public void edge(final String b, final String e) {
edge(stream, b, e);
}
}
+235 -233
View File
@@ -1,6 +1,8 @@
package org.jetbrains.ether;
import java.io.*;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.List;
/**
@@ -13,257 +15,257 @@ import java.util.List;
* The main class to start with
*/
public class Main {
private static final Options myOptions;
private static final Options myOptions;
private enum Action {
REBUILD,
MAKE,
CLEAN,
NONE
private enum Action {
REBUILD,
MAKE,
CLEAN,
NONE
}
static {
final Options.Descriptor[] descrs = {new Options.Descriptor("script", "script", "s", Options.ArgumentSpecifier.MANDATORY,
"specify script for project library/sdk setup; use prefix '@' to specify script file"),
new Options.Descriptor("inspect", "inspect", "i", Options.ArgumentSpecifier.OPTIONAL,
"list relevant information for the whole project or specified module"),
new Options.Descriptor("save", "save", "x", Options.ArgumentSpecifier.NONE, "collect and save project information"),
new Options.Descriptor("clean", "clean", "c", Options.ArgumentSpecifier.NONE, "clean project"),
new Options.Descriptor("rebuild", "rebuild", "r", Options.ArgumentSpecifier.NONE, "rebuild project"),
new Options.Descriptor("make", "make", "m", Options.ArgumentSpecifier.OPTIONAL, "make the whole project or specified module"),
new Options.Descriptor("tests", "tests", "t", Options.ArgumentSpecifier.NONE, "make tests as well"),
new Options.Descriptor("force", "force", "f", Options.ArgumentSpecifier.NONE, "force actions"),
new Options.Descriptor("incremental", "incremental", "u", Options.ArgumentSpecifier.NONE, "perform incremental make"),
new Options.Descriptor("help", "help", "h", Options.ArgumentSpecifier.NONE, "show help on options"),
new Options.Descriptor("log", "log", "l", Options.ArgumentSpecifier.OPTIONAL, "log into file (for development purposes)")};
myOptions = new Options(descrs);
}
private static PrintStream logStream = null;
private static boolean logStreamSet = false;
private static PrintStream getLog() {
if (logStreamSet) {
return logStream;
}
static {
final Options.Descriptor[] descrs = {
new Options.Descriptor("script", "script", "s", Options.ArgumentSpecifier.MANDATORY, "specify script for project library/sdk setup; use prefix '@' to specify script file"),
new Options.Descriptor("inspect", "inspect", "i", Options.ArgumentSpecifier.OPTIONAL, "list relevant information for the whole project or specified module"),
new Options.Descriptor("save", "save", "x", Options.ArgumentSpecifier.NONE, "collect and save project information"),
new Options.Descriptor("clean", "clean", "c", Options.ArgumentSpecifier.NONE, "clean project"),
new Options.Descriptor("rebuild", "rebuild", "r", Options.ArgumentSpecifier.NONE, "rebuild project"),
new Options.Descriptor("make", "make", "m", Options.ArgumentSpecifier.OPTIONAL, "make the whole project or specified module"),
new Options.Descriptor("tests", "tests", "t", Options.ArgumentSpecifier.NONE, "make tests as well"),
new Options.Descriptor("force", "force", "f", Options.ArgumentSpecifier.NONE, "force actions"),
new Options.Descriptor("incremental", "incremental", "u", Options.ArgumentSpecifier.NONE, "perform incremental make"),
new Options.Descriptor("help", "help", "h", Options.ArgumentSpecifier.NONE, "show help on options"),
new Options.Descriptor("log", "log", "l", Options.ArgumentSpecifier.OPTIONAL, "log into file (for development purposes)")
};
logStreamSet = true;
myOptions = new Options(descrs);
final Options.Argument arg = myOptions.get("log");
if (arg == null) {
return null;
}
private static PrintStream logStream = null;
private static boolean logStreamSet = false;
private static PrintStream getLog() {
if (logStreamSet) {
return logStream;
}
logStreamSet = true;
final Options.Argument arg = myOptions.get("log");
if (arg == null) {
return null;
}
if (arg instanceof Options.Value) {
try {
return logStream = new PrintStream(new FileOutputStream(((Options.Value) arg).get()));
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
if (arg instanceof Options.Switch) {
return logStream = System.out;
}
if (arg instanceof Options.Value) {
try {
return logStream = new PrintStream(new FileOutputStream(((Options.Value)arg).get()));
}
catch (IOException e) {
e.printStackTrace();
return null;
}
}
private static boolean doSave() {
return myOptions.get("save") instanceof Options.Switch;
if (arg instanceof Options.Switch) {
return logStream = System.out;
}
private static boolean doTests() {
return myOptions.get("tests") instanceof Options.Switch;
return null;
}
private static boolean doSave() {
return myOptions.get("save") instanceof Options.Switch;
}
private static boolean doTests() {
return myOptions.get("tests") instanceof Options.Switch;
}
private static boolean doRebuild() {
return myOptions.get("rebuild") instanceof Options.Switch;
}
private static boolean doForce() {
return myOptions.get("force") instanceof Options.Switch;
}
private static boolean doIncremental() {
return myOptions.get("incremental") instanceof Options.Switch;
}
private static boolean doHelp() {
return myOptions.get("help") instanceof Options.Switch;
}
private static Options.Argument doInspect() {
return myOptions.get("inspect");
}
private static Options.Argument doMake() {
return myOptions.get("make");
}
private static boolean doClean() {
return myOptions.get("clean") instanceof Options.Switch;
}
private static String getScript() {
final Options.Argument arg = myOptions.get("script");
if (arg instanceof Options.Value) return ((Options.Value)arg).get();
return null;
}
private static ProjectWrapper.Flags getFlags() {
return new ProjectWrapper.Flags() {
public boolean tests() {
return doTests();
}
public boolean force() {
return doForce();
}
public boolean incremental() {
return doIncremental();
}
public PrintStream logStream() {
return getLog();
}
};
}
private static void checkConsistency() {
int test = 0;
if (doClean()) test++;
if (doMake() != null) test++;
if (doRebuild()) test++;
if (test > 1) {
System.err.print("WARNING: Conflicting options (should be --make OR --rebuild OR --clean); preferring ");
if (doMake() != null) {
System.err.println("make.");
}
else if (doRebuild()) System.err.println("rebuild.");
}
private static boolean doRebuild() {
return myOptions.get("rebuild") instanceof Options.Switch;
if (doClean() || doRebuild()) {
if (doTests()) {
System.err.println("WARNING: extra --tests option ignored.");
}
if (doForce()) {
System.err.println("WARNING: extra --force option ignored.");
}
}
}
private static Action getAction() {
if (doMake() != null) {
return Action.MAKE;
}
private static boolean doForce() {
return myOptions.get("force") instanceof Options.Switch;
if (doRebuild()) return Action.REBUILD;
if (doClean()) return Action.CLEAN;
return Action.NONE;
}
public static void main(String[] args) {
System.out.println("JetBrains.com build server. (C) JetBrains.com, 2010-2011.\n");
final List<String> notes = myOptions.parse(args);
for (String note : notes) {
System.err.println("WARNING: " + note);
}
private static boolean doIncremental() {
return myOptions.get("incremental") instanceof Options.Switch;
checkConsistency();
if (doHelp()) {
System.out.println("Usage: ??? <options> <project-specifier>\n");
System.out.println("Options are:");
System.out.println(myOptions.memo());
}
final List<String> projects = myOptions.getFree();
if (projects.isEmpty() && !doHelp()) {
System.out.println("Nothing to do; use --help or -h option to see the help.\n");
}
for (String prj : projects) {
boolean saved = false;
ProjectWrapper project = null;
switch (getAction()) {
case CLEAN:
System.out.println("Cleaning project \"" + prj + "\"");
project = ProjectWrapper.load(prj, getScript(), false);
project.clean();
project.save();
saved = true;
break;
case REBUILD:
System.out.println("Rebuilding project \"" + prj + "\"");
project = ProjectWrapper.load(prj, getScript(), false);
project.rebuild();
project.save();
saved = true;
break;
case MAKE:
final Options.Argument make = doMake();
if (make instanceof Options.Value) {
final String module = ((Options.Value)make).get();
System.out.println("Making module \"" + module + "\" in project \"" + prj + "\"");
project = ProjectWrapper.load(prj, getScript(), true);
project.makeModule(module, getFlags());
project.save();
saved = true;
}
else if (make instanceof Options.Switch) {
System.out.println("Making all modules in project \"" + prj + "\"");
project = ProjectWrapper.load(prj, getScript(), true);
project.makeModule(null, getFlags());
project.save();
saved = true;
}
;
break;
}
final Options.Argument inspect = doInspect();
if (inspect instanceof Options.Switch) {
project = ProjectWrapper.load(prj, getScript(), true);
project.report();
if (doSave()) {
project.save();
saved = true;
}
private static boolean doHelp() {
return myOptions.get("help") instanceof Options.Switch;
}
private static Options.Argument doInspect() {
return myOptions.get("inspect");
}
private static Options.Argument doMake() {
return myOptions.get("make");
}
private static boolean doClean() {
return myOptions.get("clean") instanceof Options.Switch;
}
private static String getScript() {
final Options.Argument arg = myOptions.get("script");
if (arg instanceof Options.Value)
return ((Options.Value) arg).get();
return null;
}
private static ProjectWrapper.Flags getFlags () {
return new ProjectWrapper.Flags() {
public boolean tests () {
return doTests();
}
public boolean force () {
return doForce();
}
public boolean incremental () {
return doIncremental();
}
public PrintStream logStream () {
return getLog();
}
};
}
private static void checkConsistency() {
int test = 0;
if (doClean()) test++;
if (doMake() != null) test++;
if (doRebuild()) test++;
if (test > 1) {
System.err.print("WARNING: Conflicting options (should be --make OR --rebuild OR --clean); preferring ");
if (doMake() != null)
System.err.println("make.");
else if (doRebuild())
System.err.println("rebuild.");
}
else if (inspect instanceof Options.Value) {
project = ProjectWrapper.load(prj, getScript(), true);
project.report(((Options.Value)inspect).get());
if (doSave()) {
project.save();
saved = true;
}
}
if (doClean() || doRebuild()) {
if (doTests()) {
System.err.println("WARNING: extra --tests option ignored.");
}
if (doForce()) {
System.err.println("WARNING: extra --force option ignored.");
}
}
}
private static Action getAction() {
if (doMake() != null) {
return Action.MAKE;
}
if (doRebuild())
return Action.REBUILD;
if (doClean())
return Action.CLEAN;
return Action.NONE;
}
public static void main(String[] args) {
System.out.println("JetBrains.com build server. (C) JetBrains.com, 2010-2011.\n");
final List<String> notes = myOptions.parse(args);
for (String note : notes) {
System.err.println("WARNING: " + note);
}
checkConsistency();
if (doHelp()) {
System.out.println("Usage: ??? <options> <project-specifier>\n");
System.out.println("Options are:");
System.out.println(myOptions.memo());
}
final List<String> projects = myOptions.getFree();
if (projects.isEmpty() && !doHelp()) {
System.out.println("Nothing to do; use --help or -h option to see the help.\n");
}
for (String prj : projects) {
boolean saved = false;
ProjectWrapper project = null;
switch (getAction()) {
case CLEAN:
System.out.println("Cleaning project \"" + prj + "\"");
project = ProjectWrapper.load(prj, getScript(), false);
project.clean();
project.save();
saved = true;
break;
case REBUILD:
System.out.println("Rebuilding project \"" + prj + "\"");
project = ProjectWrapper.load(prj, getScript(), false);
project.rebuild();
project.save();
saved = true;
break;
case MAKE:
final Options.Argument make = doMake();
if (make instanceof Options.Value) {
final String module = ((Options.Value) make).get();
System.out.println("Making module \"" + module + "\" in project \"" + prj + "\"");
project = ProjectWrapper.load(prj, getScript(), true);
project.makeModule(module, getFlags ());
project.save();
saved = true;
} else if (make instanceof Options.Switch) {
System.out.println("Making all modules in project \"" + prj + "\"");
project = ProjectWrapper.load(prj, getScript(), true);
project.makeModule(null, getFlags ());
project.save();
saved = true;
}
;
break;
}
final Options.Argument inspect = doInspect();
if (inspect instanceof Options.Switch) {
project = ProjectWrapper.load(prj, getScript(), true);
project.report();
if (doSave()) {
project.save();
saved = true;
}
} else if (inspect instanceof Options.Value) {
project = ProjectWrapper.load(prj, getScript(), true);
project.report(((Options.Value) inspect).get());
if (doSave()) {
project.save();
saved = true;
}
}
if (doSave() && !saved) {
project = ProjectWrapper.load(prj, getScript(), true);
project.save();
}
}
if (doSave() && !saved) {
project = ProjectWrapper.load(prj, getScript(), true);
project.save();
}
}
}
}
+95 -96
View File
@@ -1,6 +1,5 @@
package org.jetbrains.ether;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.util.*;
@@ -13,116 +12,116 @@ import java.util.*;
* To change this template use File | Settings | File Templates.
*/
public class MockFS {
final Map<java.io.File, File> myFiles = new HashMap<java.io.File, File>();
final File myRoot;
final Map<java.io.File, File> myFiles = new HashMap<java.io.File, File>();
final File myRoot;
private File getFile(java.io.File f) {
if (f.getAbsolutePath().startsWith(myRoot.getAbsolutePath())) {
File g = myFiles.get(f);
private File getFile(java.io.File f) {
if (f.getAbsolutePath().startsWith(myRoot.getAbsolutePath())) {
File g = myFiles.get(f);
if (g != null) {
return g;
}
if (g != null) {
return g;
}
g = new File(f, false);
g = new File(f, false);
myFiles.put(f, g);
myFiles.put(f, g);
return g;
}
return null;
return g;
}
public class File extends java.io.File {
final Set<File> mySubFiles = new HashSet<File>();
final File myParent;
return null;
}
private File(final java.io.File file, final boolean root) {
super(file.getPath());
public class File extends java.io.File {
final Set<File> mySubFiles = new HashSet<File>();
final File myParent;
if (root) {
myParent = null;
return;
}
private File(final java.io.File file, final boolean root) {
super(file.getPath());
final java.io.File parent = file.getParentFile();
if (root) {
myParent = null;
return;
}
myParent = parent == null ? null : getFile(parent);
final java.io.File parent = file.getParentFile();
if (myParent != null) {
myParent.mySubFiles.add(this);
}
}
myParent = parent == null ? null : getFile(parent);
@Override
public String[] list() {
return list(new FilenameFilter() {
public boolean accept(java.io.File dir, String name) {
return true;
}
});
}
@Override
public String[] list(final FilenameFilter filter) {
final List<String> result = new LinkedList<String>();
for (final File f : mySubFiles) {
if (filter.accept(this, f.getName())) {
result.add(f.getName());
}
}
return result.toArray(new String[result.size()]);
}
@Override
public java.io.File[] listFiles() {
return mySubFiles.toArray(new File[mySubFiles.size()]);
}
@Override
public java.io.File[] listFiles(final FilenameFilter filter) {
final List<File> result = new LinkedList<File>();
for (File f : mySubFiles) {
if (filter.accept(this, f.getName())) {
result.add(f);
}
}
return result.toArray(new File[result.size()]);
}
@Override
public java.io.File[] listFiles(final FileFilter filter) {
final List<File> result = new LinkedList<File>();
for (File f : mySubFiles) {
if (filter.accept(f)) {
result.add(f);
}
}
return result.toArray(new File[result.size()]);
}
if (myParent != null) {
myParent.mySubFiles.add(this);
}
}
private MockFS(final String root) {
final java.io.File rootFile = new java.io.File(root);
myRoot = new File(rootFile, true);
myFiles.put(rootFile, myRoot);
}
public static File fromFiles(final String root, final Collection<String> files) {
final MockFS fs = new MockFS(root);
for (String f : files) {
fs.getFile(new java.io.File (f));
@Override
public String[] list() {
return list(new FilenameFilter() {
public boolean accept(java.io.File dir, String name) {
return true;
}
return fs.myRoot;
});
}
@Override
public String[] list(final FilenameFilter filter) {
final List<String> result = new LinkedList<String>();
for (final File f : mySubFiles) {
if (filter.accept(this, f.getName())) {
result.add(f.getName());
}
}
return result.toArray(new String[result.size()]);
}
@Override
public java.io.File[] listFiles() {
return mySubFiles.toArray(new File[mySubFiles.size()]);
}
@Override
public java.io.File[] listFiles(final FilenameFilter filter) {
final List<File> result = new LinkedList<File>();
for (File f : mySubFiles) {
if (filter.accept(this, f.getName())) {
result.add(f);
}
}
return result.toArray(new File[result.size()]);
}
@Override
public java.io.File[] listFiles(final FileFilter filter) {
final List<File> result = new LinkedList<File>();
for (File f : mySubFiles) {
if (filter.accept(f)) {
result.add(f);
}
}
return result.toArray(new File[result.size()]);
}
}
private MockFS(final String root) {
final java.io.File rootFile = new java.io.File(root);
myRoot = new File(rootFile, true);
myFiles.put(rootFile, myRoot);
}
public static File fromFiles(final String root, final Collection<String> files) {
final MockFS fs = new MockFS(root);
for (String f : files) {
fs.getFile(new java.io.File(f));
}
return fs.myRoot;
}
}
+217 -206
View File
@@ -16,240 +16,251 @@ import java.util.regex.Pattern;
*/
public class Options {
public enum ArgumentSpecifier {
MANDATORY,
OPTIONAL,
NONE;
public enum ArgumentSpecifier {
MANDATORY,
OPTIONAL,
NONE;
}
public abstract interface Argument {
}
public static class Switch implements Argument {
}
private static Switch SWITCH = new Switch();
public static class Value implements Argument {
private final String myValue;
Value(final String s) {
myValue = s;
}
public abstract interface Argument {
public String get() {
return myValue;
}
}
private class Cursor {
int myPos;
final int myLength;
final String[] myArgs;
Cursor(final String[] args) {
myArgs = args;
myPos = 0;
myLength = myArgs.length;
}
public static class Switch implements Argument {
public String look() {
if (myPos >= myLength) return null;
return myArgs[myPos];
}
private static Switch SWITCH = new Switch();
public static class Value implements Argument {
private final String myValue;
Value (final String s) {
myValue = s;
}
public String get () {
return myValue;
}
public void shift() {
myPos++;
}
private class Cursor {
int myPos;
final int myLength;
final String[] myArgs;
public String lookahead() {
final String arg = myArgs[myPos + 1];
myPos += 2;
Cursor (final String[] args) {
myArgs = args;
myPos = 0;
myLength = myArgs.length;
}
public String look () {
if (myPos >= myLength)
return null;
return myArgs [myPos];
}
public void shift () {
myPos++;
}
public String lookahead () {
final String arg = myArgs[myPos+1];
myPos += 2;
return arg;
}
public boolean nextIsArg () {
return (myPos < myLength - 1 && ! myArgs[myPos+1].startsWith("-"));
}
public boolean endOf () {
return myPos >= myLength;
}
return arg;
}
private interface Callback {
void update (String key, Argument value);
void addFree (String value);
void report (String note);
public boolean nextIsArg() {
return (myPos < myLength - 1 && !myArgs[myPos + 1].startsWith("-"));
}
public static class Descriptor {
private final ArgumentSpecifier myArgumentSpecifier;
private final String myKey;
private final String myLong;
private final String myShort;
private final String myMemo;
public boolean endOf() {
return myPos >= myLength;
}
}
private final Pattern myLongPattern;
private interface Callback {
void update(String key, Argument value);
Descriptor (final String key, final String longForm, final String shortForm, final ArgumentSpecifier as, final String memo) {
myArgumentSpecifier = as;
myKey = key;
myLong = longForm;
myShort = shortForm;
myMemo = memo;
void addFree(String value);
myLongPattern = myLong == null ? null : Pattern.compile("^--" + myLong + "(=(.*))?$");
}
void report(String note);
}
public String memo () {
final StringBuilder buf = new StringBuilder();
String longArg = "", shortArg = "";
public static class Descriptor {
private final ArgumentSpecifier myArgumentSpecifier;
private final String myKey;
private final String myLong;
private final String myShort;
private final String myMemo;
switch (myArgumentSpecifier) {
private final Pattern myLongPattern;
Descriptor(final String key, final String longForm, final String shortForm, final ArgumentSpecifier as, final String memo) {
myArgumentSpecifier = as;
myKey = key;
myLong = longForm;
myShort = shortForm;
myMemo = memo;
myLongPattern = myLong == null ? null : Pattern.compile("^--" + myLong + "(=(.*))?$");
}
public String memo() {
final StringBuilder buf = new StringBuilder();
String longArg = "", shortArg = "";
switch (myArgumentSpecifier) {
case OPTIONAL:
longArg = "[=<argument>]";
shortArg = " [<argument>]";
break;
case NONE:
longArg = "";
shortArg = "";
break;
case MANDATORY:
longArg = "=<argument>";
shortArg = " <argument>";
break;
}
buf.append(" --" + myLong + longArg + ", -" + myShort + shortArg + "\n");
buf.append(" " + myMemo + "\n");
return buf.toString();
}
public boolean proceed(final Cursor cursor, final Callback callback) {
if (cursor.endOf()) return false;
final String arg = cursor.look();
if (!arg.startsWith("-")) {
callback.addFree(arg);
cursor.shift();
return true;
}
if (myShort != null && arg.equals("-" + myShort)) {
switch (myArgumentSpecifier) {
case NONE:
callback.update(myKey, SWITCH);
break;
default:
if (cursor.nextIsArg()) {
callback.update(myKey, new Value(cursor.lookahead()));
}
else {
switch (myArgumentSpecifier) {
case OPTIONAL:
longArg = "[=<argument>]";
shortArg = " [<argument>]";
break;
case NONE:
longArg = "";
shortArg = "";
break;
callback.update(myKey, SWITCH);
break;
case MANDATORY:
longArg = "=<argument>";
shortArg = " <argument>";
break;
}
buf.append(" --" + myLong + longArg + ", -" + myShort + shortArg + "\n");
buf.append(" " + myMemo + "\n");
return buf.toString();
}
public boolean proceed (final Cursor cursor, final Callback callback) {
if (cursor.endOf())
return false;
final String arg = cursor.look();
if (! arg.startsWith("-")) {
callback.addFree(arg);
cursor.shift();
return true;
}
if (myShort != null && arg.equals("-" + myShort)) {
switch (myArgumentSpecifier) {
case NONE:
callback.update(myKey, SWITCH);
break;
default:
if (cursor.nextIsArg())
callback.update(myKey, new Value(cursor.lookahead()));
else
switch (myArgumentSpecifier) {
case OPTIONAL:
callback.update(myKey, SWITCH);
break;
case MANDATORY:
callback.report("option \"" + arg + "\" requires an argument, discarding.");
}
};
cursor.shift();
return true;
}
final Matcher m = myLongPattern.matcher(arg);
if (myLong != null && m.matches()) {
final String prm = m.group(2);
switch (myArgumentSpecifier) {
case MANDATORY:
if (prm == null)
callback.report("option \"" + arg + "\" requires an argument, discarding.");
else
callback.update(myKey, new Value (prm));
break;
case NONE:
if (prm == null)
callback.update(myKey, SWITCH);
else
callback.report("option \"" + arg + "\" does not take an argument, omitting.");
break;
case OPTIONAL:
callback.update(myKey, prm == null ? SWITCH : new Value(prm));
break;
}
cursor.shift();
return true;
}
return false;
}
}
private Map<String, Argument> myOptions = new HashMap<String, Argument> ();
private List<String> myFree;
private final Descriptor[] myDescriptors;
Options (final Descriptor[] descrs) {
myDescriptors = descrs;
}
public List<String> parse (final String[] args) {
myOptions.clear();
myFree = new ArrayList<String> ();
final List<String> notes = new ArrayList<String> ();
final Callback cb = new Callback() {
public void addFree (final String value) {
myFree.add(value);
}
public void update (final String key, final Argument value) {
myOptions.put(key, value);
}
public void report (final String note) {
notes.add(note);
}
};
final Cursor cursor = new Cursor(args);
while (!cursor.endOf()) {
boolean recognized = false;
for (int i = 0; i<myDescriptors.length; i++)
recognized |= myDescriptors[i].proceed(cursor, cb);
if (!recognized) {
cb.report("unrecognized option \"" + cursor.look() + "\" omitted.");
cursor.shift();
callback.report("option \"" + arg + "\" requires an argument, discarding.");
}
}
}
;
return notes;
cursor.shift();
return true;
}
final Matcher m = myLongPattern.matcher(arg);
if (myLong != null && m.matches()) {
final String prm = m.group(2);
switch (myArgumentSpecifier) {
case MANDATORY:
if (prm == null) {
callback.report("option \"" + arg + "\" requires an argument, discarding.");
}
else {
callback.update(myKey, new Value(prm));
}
break;
case NONE:
if (prm == null) {
callback.update(myKey, SWITCH);
}
else {
callback.report("option \"" + arg + "\" does not take an argument, omitting.");
}
break;
case OPTIONAL:
callback.update(myKey, prm == null ? SWITCH : new Value(prm));
break;
}
cursor.shift();
return true;
}
return false;
}
}
private Map<String, Argument> myOptions = new HashMap<String, Argument>();
private List<String> myFree;
private final Descriptor[] myDescriptors;
Options(final Descriptor[] descrs) {
myDescriptors = descrs;
}
public List<String> parse(final String[] args) {
myOptions.clear();
myFree = new ArrayList<String>();
final List<String> notes = new ArrayList<String>();
final Callback cb = new Callback() {
public void addFree(final String value) {
myFree.add(value);
}
public void update(final String key, final Argument value) {
myOptions.put(key, value);
}
public void report(final String note) {
notes.add(note);
}
};
final Cursor cursor = new Cursor(args);
while (!cursor.endOf()) {
boolean recognized = false;
for (int i = 0; i < myDescriptors.length; i++) {
recognized |= myDescriptors[i].proceed(cursor, cb);
}
if (!recognized) {
cb.report("unrecognized option \"" + cursor.look() + "\" omitted.");
cursor.shift();
}
}
public Argument get (final String name) {
return myOptions.get(name);
}
return notes;
}
public List<String> getFree () {
return myFree;
}
public Argument get(final String name) {
return myOptions.get(name);
}
public String memo () {
public List<String> getFree() {
return myFree;
}
public String memo() {
final StringBuilder buf = new StringBuilder();
for (final Descriptor descriptor : myDescriptors) {
-38
View File
@@ -1,38 +0,0 @@
package org.jetbrains.ether;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 19.06.11
* Time: 16:48
* To change this template use File | Settings | File Templates.
*/
public class Pair<X, Y> {
public final X fst;
public final Y snd;
public Pair(final X fst, final Y snd) {
this.fst = fst;
this.snd = snd;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pair pair = (Pair) o;
if (!fst.equals(pair.fst)) return false;
if (!snd.equals(pair.snd)) return false;
return true;
}
@Override
public int hashCode() {
int result = fst.hashCode();
result = 31 * result + snd.hashCode();
return result;
}
}
+21 -32
View File
@@ -1,5 +1,6 @@
package org.jetbrains.ether;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import org.codehaus.gant.GantBinding;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
@@ -58,7 +59,7 @@ public class ProjectWrapper {
public void logFilePaths(PrintStream stream, Collection<StringCache.S> paths) {
List<String> strings = new ArrayList<String>(paths.size());
for (StringCache.S path : paths) {
strings.add(FileUtil.toSystemIndependentName(path.toString()));
strings.add(FileUtil.toSystemIndependentName(getRelativePath(path.toString())));
}
logMany(stream, strings);
}
@@ -148,7 +149,7 @@ public class ProjectWrapper {
public LibraryWrapper(final Library lib) {
lib.forceInit();
myName = lib.getName();
myClassPath = (List<String>)getRelativePaths(lib.getClasspath(), new ArrayList<String>());
myClassPath = lib.getClasspath();
}
public String getName() {
@@ -246,7 +247,7 @@ public class ProjectWrapper {
myType = null;
}
myClassPath = (List<String>)getRelativePaths(item.getClasspathRoots(null), new ArrayList<String>());
myClassPath = item.getClasspathRoots(null);
}
public GenericClasspathItemWrapper(final BufferedReader r) {
@@ -282,7 +283,7 @@ public class ProjectWrapper {
final long myModificationTime;
FileWrapper(final File f) {
myName = StringCache.get(getRelativePath(f.getAbsolutePath()));
myName = StringCache.get(f.getAbsolutePath());
myModificationTime = f.lastModified();
}
@@ -446,7 +447,7 @@ public class ProjectWrapper {
}
public Properties(final List<String> sources, final String output, final Set<String> excludes) {
myRoots = (Set<String>)getRelativePaths(sources, new HashSet<String>());
myRoots = new HashSet<String>(sources);
final DirectoryScanner.Result result = DirectoryScanner.getFiles(myRoots, excludes, ProjectWrapper.this);
mySources = new HashMap<FileWrapper, FileWrapper>();
@@ -455,12 +456,12 @@ public class ProjectWrapper {
mySources.put(fw, fw);
}
myOutput = getRelativePath(output);
myOutput = output;
updateOutputStatus();
}
public void updateOutputStatus() {
final String path = getAbsolutePath(myOutput);
final String path = myOutput;
final File ok = new File(path + File.separator + Reporter.myOkFlag);
final File fail = new File(path + File.separator + Reporter.myFailFlag);
@@ -611,7 +612,7 @@ public class ProjectWrapper {
myDependsOn = null;
myTestDependsOn = null;
myName = m.getName();
myExcludes = (Set<String>)getRelativePaths(m.getExcludes(), new HashSet<String>());
myExcludes = new HashSet<String> (m.getExcludes());
mySource = new Properties(m.getSourceRoots(), m.getOutputPath(), myExcludes);
myTest = new Properties(m.getTestRoots(), m.getTestOutputPath(), myExcludes);
@@ -865,7 +866,7 @@ public class ProjectWrapper {
final String setupScript,
final Map<String, String> pathVariables,
final boolean loadHistory) {
dependencyMapping = new Mappings(this);
dependencyMapping = new Mappings();
backendCallback = dependencyMapping.getCallback();
affectedFiles = new HashSet<StringCache.S>();
@@ -925,7 +926,7 @@ public class ProjectWrapper {
RW.readMany(r, StringCache.reader, affectedFiles);
}
public String getAbsolutePath(final String relative) {
private String getAbsolutePath(final String relative) {
if (relative == null) return relative;
if (new File(relative).isAbsolute()) return relative;
@@ -933,7 +934,7 @@ public class ProjectWrapper {
return myRoot + File.separator + relative;
}
public String getRelativePath(final String absolute) {
private String getRelativePath(final String absolute) {
if (absolute == null) return absolute;
if (absolute.startsWith(myRoot)) {
@@ -943,22 +944,6 @@ public class ProjectWrapper {
return absolute;
}
public Collection<String> getAbsolutePaths(final Collection<String> paths, final Collection<String> result) {
for (String path : paths) {
if (path != null) result.add(getAbsolutePath(path));
}
return result;
}
public Collection<String> getRelativePaths(final Collection<String> paths, final Collection<String> result) {
for (String path : paths) {
if (path != null) result.add(getRelativePath(path));
}
return result;
}
private boolean isHistory() {
return myProject == null;
}
@@ -1160,7 +1145,7 @@ public class ProjectWrapper {
builder.clearChunk(chunk, outputFiles, ProjectWrapper.this);
}
final Mappings delta = new Mappings(ProjectWrapper.this);
final Mappings delta = new Mappings();
final Callbacks.Backend deltaBackend = delta.getCallback();
new Logger(flags) {
@@ -1186,9 +1171,10 @@ public class ProjectWrapper {
compiledFiles.addAll(filesToCompile);
affectedFiles.removeAll(filesToCompile);
final boolean incremental = dependencyMapping.differentiate(delta, removed, filesToCompile, compiledFiles, affectedFiles, safeFiles);
final boolean incremental =
dependencyMapping.differentiate(delta, removed, filesToCompile, compiledFiles, affectedFiles, safeFiles);
dependencyMapping.integrate(delta, removed);
dependencyMapping.integrate(delta, filesToCompile, removed);
if (!incremental) {
affectedFiles.addAll(sources);
@@ -1274,7 +1260,7 @@ public class ProjectWrapper {
cleared.addAll(toClean);
}
final Mappings delta = new Mappings(ProjectWrapper.this);
final Mappings delta = new Mappings();
final Callbacks.Backend deltaCallback = delta.getCallback();
try {
@@ -1285,12 +1271,15 @@ public class ProjectWrapper {
return BuildStatus.FAILURE;
}
final Set<StringCache.S> allFiles = new HashSet<StringCache.S>();
for (Module m : c.getElements()) {
final ModuleWrapper module = getModule(m.getName());
affectedFiles.removeAll(module.getSources(flags.tests()));
allFiles.addAll(module.getSources(flags.tests()));
}
dependencyMapping.integrate(delta, removedSources);
dependencyMapping.integrate(delta, allFiles, removedSources);
for (Module m : chunkModules) {
Reporter.reportBuildSuccess(m, flags.tests());
-223
View File
@@ -1,223 +0,0 @@
package org.jetbrains.ether;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.Collection;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 29.01.11
* Time: 21:10
* To change this template use File | Settings | File Templates.
*/
public class RW {
public interface Writable {
public void write(BufferedWriter w);
}
public static <T extends Comparable> void writeln(final BufferedWriter w, final Collection<T> c, final ToWritable<T> t) {
if (c == null) {
writeln(w, "0");
return;
}
writeln(w, Integer.toString(c.size()));
for (T e : c) {
t.convert(e).write(w);
}
}
public static void writeEncodedString(final BufferedWriter w, final String val) {
final int size = val == null ? 0 : val.length();
writeln(w, Integer.toString(size));
for (int i = 0; i < size; i++) {
writeln(w, Integer.toString((int) val.charAt(i)));
}
}
public static void writeln(final BufferedWriter w, final Collection<? extends Writable> c) {
if (c == null) {
writeln(w, "0");
return;
}
writeln(w, Integer.toString(c.size()));
for (Writable e : c) {
e.write(w);
}
}
public interface ToWritable<T> {
public Writable convert(T x);
}
public static <T> void writeln(final BufferedWriter w, final T[] c, final ToWritable<T> t) {
if (c == null) {
writeln(w, "0");
return;
}
writeln(w, Integer.toString(c.length));
for (int i = 0; i < c.length; i++) {
t.convert(c[i]).write(w);
}
}
public static <T extends Writable> void writeln(final BufferedWriter w, final T[] c) {
if (c == null) {
writeln(w, "0");
return;
}
writeln(w, Integer.toString(c.length));
for (int i = 0; i < c.length; i++) {
c[i].write(w);
}
}
public static void writeln(final BufferedWriter w, final String s) {
try {
if (s == null)
w.write("");
else
w.write(s);
w.newLine();
} catch (IOException e) {
e.printStackTrace();
}
}
public interface Reader<T> {
public T read(BufferedReader r);
}
public static ToWritable<String> fromString = new ToWritable<String>() {
public Writable convert(final String s) {
return new Writable() {
public void write(BufferedWriter w) {
writeln(w, s);
}
};
}
};
public static ToWritable<Writable> fromWritable = new ToWritable<Writable>() {
public Writable convert(final Writable w) {
return w;
}
};
public static Reader<String> myStringReader = new Reader<String>() {
public String read(final BufferedReader r) {
try {
return r.readLine();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
};
public static <T> Collection<T> readMany(final BufferedReader r, final Reader<T> c, final Collection<T> acc) {
final int size = readInt(r);
for (int i = 0; i < size; i++) {
acc.add(c.read(r));
}
return acc;
}
public static String lookString(final BufferedReader r) {
try {
r.mark(256);
final String s = r.readLine();
r.reset();
return s;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static void readTag(final BufferedReader r, final String tag) {
try {
final String s = r.readLine();
if (!s.equals(tag))
System.err.println("Parsing error: expected \"" + tag + "\", but found \"" + s + "\"");
} catch (IOException e) {
e.printStackTrace();
}
}
public static String readString(final BufferedReader r) {
try {
return r.readLine();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static String readEncodedString(final BufferedReader r) {
final StringBuilder b = new StringBuilder();
final int size = readInt(r);
for (int i = 0; i < size; i++) {
final int c = readInt(r);
b.append((char) c);
}
return b.toString();
}
public static long readLong(final BufferedReader r) {
final String s = readString(r);
try {
return Long.parseLong(s);
} catch (Exception n) {
System.err.println("Parsing error: expected long, but found \"" + s + "\"");
return 0;
}
}
public static int readInt(final BufferedReader r) {
final String s = readString(r);
try {
return Integer.parseInt(s);
} catch (Exception n) {
System.err.println("Parsing error: expected integer, but found \"" + s + "\"");
return 0;
}
}
public static String readStringAttribute(final BufferedReader r, final String tag) {
try {
final String s = r.readLine();
if (s.startsWith(tag))
return s.substring(tag.length());
System.err.println("Parsing error: expected \"" + tag + "\", but found \"" + s + "\"");
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
+69 -70
View File
@@ -2,7 +2,9 @@ package org.jetbrains.ether;
import org.jetbrains.jps.Module;
import java.io.*;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
/**
* Created by IntelliJ IDEA.
@@ -12,91 +14,88 @@ import java.io.*;
* To change this template use File | Settings | File Templates.
*/
public class Reporter {
public static final String myOkFlag = ".jps.ok";
public static final String myFailFlag = ".jps.fail";
public static final String myOkFlag = ".jps.ok";
public static final String myFailFlag = ".jps.fail";
private static String getSafePath (final String path) {
final File f = new File(path);
private static String getSafePath(final String path) {
final File f = new File(path);
if (! f.exists()) {
f.mkdir();
}
return path;
if (!f.exists()) {
f.mkdir();
}
private static String getOkFlag(final Module m) {
final String outputPath = m.getOutputPath();
return path;
}
if (outputPath == null)
return null;
private static String getOkFlag(final Module m) {
final String outputPath = m.getOutputPath();
return getSafePath (outputPath) + File.separator + myOkFlag;
if (outputPath == null) return null;
return getSafePath(outputPath) + File.separator + myOkFlag;
}
private static String getFailFlag(final Module m) {
final String outputPath = m.getOutputPath();
if (outputPath == null) return null;
return getSafePath(outputPath) + File.separator + myFailFlag;
}
private static String getOkTestFlag(final Module m) {
final String testOutputPath = m.getTestOutputPath();
if (testOutputPath == null) return null;
return getSafePath(testOutputPath) + File.separator + myOkFlag;
}
private static String getFailTestFlag(final Module m) {
final String testOutputPath = m.getTestOutputPath();
if (testOutputPath == null) {
return null;
}
private static String getFailFlag(final Module m) {
final String outputPath = m.getOutputPath();
return getSafePath(testOutputPath) + File.separator + myFailFlag;
}
if (outputPath == null)
return null;
private static void write(final String name, final String contents) {
if (name == null) return;
try {
final File file = new File(name);
final String path = file.getParent();
new File(path).mkdirs();
final FileWriter writer = new FileWriter(name);
writer.write(contents);
writer.close();
return getSafePath (outputPath) + File.separator + myFailFlag;
}
private static String getOkTestFlag(final Module m) {
final String testOutputPath = m.getTestOutputPath();
if (testOutputPath == null)
return null;
return getSafePath (testOutputPath) + File.separator + myOkFlag;
catch (IOException e) {
throw new RuntimeException(e);
}
}
private static String getFailTestFlag(final Module m) {
final String testOutputPath = m.getTestOutputPath();
if (testOutputPath == null) {
return null;
}
return getSafePath(testOutputPath) + File.separator + myFailFlag;
public static void reportBuildSuccess(final Module m, final boolean tests) {
if (tests) {
write(getOkTestFlag(m), "dummy");
}
private static void write(final String name, final String contents) {
if (name == null)
return;
try {
final File file = new File (name);
final String path = file.getParent();
new File (path).mkdirs();
final FileWriter writer = new FileWriter(name);
writer.write(contents);
writer.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
else {
write(getOkFlag(m), "dummy");
}
}
public static void reportBuildSuccess(final Module m, final boolean tests) {
if (tests) {
write(getOkTestFlag(m), "dummy");
}
else {
write(getOkFlag(m), "dummy");
}
public static void reportBuildFailure(final Module m, final boolean tests, final String reason) {
if (tests) {
write(getFailTestFlag(m), reason);
}
public static void reportBuildFailure(final Module m, final boolean tests, final String reason) {
if (tests) {
write(getFailTestFlag(m), reason);
}
else {
write(getFailFlag(m), reason);
}
else {
write(getFailFlag(m), reason);
}
}
}
@@ -22,282 +22,286 @@ import java.util.regex.Pattern;
* To change this template use File | Settings | File Templates.
*/
public class AntListener implements BuildListener {
private static final Pattern read = Pattern.compile("\\[parsing started (.*)\\]");
private static final Pattern written = Pattern.compile("\\[wrote (.*)\\]");
private static final Pattern read = Pattern.compile("\\[parsing started (.*)\\]");
private static final Pattern written = Pattern.compile("\\[wrote (.*)\\]");
private final Map<String, List<String>> readFiles = new HashMap<String, List<String>>();
private final Map<String, List<ClassFileInfo>> writtenFiles = new HashMap<String, List<ClassFileInfo>>();
private final String targetFolder;
private final int stripLength;
private final List<String> sourceRoots;
private final Callbacks.Backend callback;
private final Map<String, List<String>> readFiles = new HashMap<String, List<String>>();
private final Map<String, List<ClassFileInfo>> writtenFiles = new HashMap<String, List<ClassFileInfo>>();
private final String targetFolder;
private final int stripLength;
private final List<String> sourceRoots;
private final Callbacks.Backend callback;
private static String basename(final String name, final String extension) {
return name.substring(0, name.length() - extension.length());
private static String basename(final String name, final String extension) {
return name.substring(0, name.length() - extension.length());
}
private static ClassReader getClassReader(final String fullName) {
try {
final File f = new File(fullName);
final byte[] buffer = new byte[(int)f.length()];
final FileInputStream i = new FileInputStream(f);
final int n = i.read(buffer);
i.close();
assert ((int)f.length() == n);
return new ClassReader(buffer);
}
catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
return null;
}
}
private class ClassFileInfo {
final String packageName;
final String fullName;
List<String> subClasses = null;
public ClassFileInfo(final String fullName, final String packageName) {
this.packageName = packageName;
this.fullName = fullName;
}
private static ClassReader getClassReader(final String fullName) {
try {
final File f = new File(fullName);
final byte[] buffer = new byte[(int) f.length()];
final FileInputStream i = new FileInputStream(f);
public void attachSubClass(final String name) {
if (subClasses == null) {
subClasses = new LinkedList<String>();
}
final int n = i.read(buffer);
i.close();
assert ((int) f.length() == n);
return new ClassReader(buffer);
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
return null;
}
subClasses.add(name);
}
private class ClassFileInfo {
final String packageName;
final String fullName;
List<String> subClasses = null;
public String getFullName() {
return fullName;
}
public ClassFileInfo(final String fullName, final String packageName) {
this.packageName = packageName;
this.fullName = fullName;
public String getPackageName() {
return packageName;
}
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append(" Root: ").append(fullName).append(", package ").append(packageName).append("\n");
builder.append(" Subclasses:");
if (subClasses != null) {
for (String s : subClasses) {
builder.append(" ").append(s);
}
}
builder.append(".\n");
return builder.toString();
}
public void associate(final Callbacks.SourceFileNameLookup sourceFileNameLookup) {
if (callback != null) {
callback.associate(fullName, sourceFileNameLookup, getClassReader(fullName));
if (subClasses != null) {
for (String s : subClasses) {
callback.associate(s, sourceFileNameLookup, getClassReader(s));
}
}
}
}
}
public AntListener(final String targetFolder, final List<String> sourceRoots, final Callbacks.Backend callback) {
this.targetFolder = targetFolder;
this.sourceRoots = sourceRoots;
this.callback = callback;
stripLength = targetFolder.length() + 1;
}
public void buildStarted(BuildEvent event) {
//To change body of implemented methods use File | Settings | File Templates.
}
public void buildFinished(BuildEvent event) {
//To change body of implemented methods use File | Settings | File Templates.
}
public void targetStarted(BuildEvent event) {
//To change body of implemented methods use File | Settings | File Templates.
}
public void targetFinished(BuildEvent event) {
//To change body of implemented methods use File | Settings | File Templates.
}
public void taskStarted(BuildEvent event) {
}
public void taskFinished(BuildEvent event) {
if (event.getTask().getTaskName().equals("javac")) {
for (Map.Entry<String, List<ClassFileInfo>> e : writtenFiles.entrySet()) {
final String className = e.getKey();
final List<ClassFileInfo> infos = e.getValue();
final List<String> read = readFiles.get(className);
if (infos.size() == 1 && read != null && read.size() == 1) {
infos.get(0).associate(Callbacks.getDefaultLookup(read.get(0)));
continue;
}
public void attachSubClass(final String name) {
if (subClasses == null) {
subClasses = new LinkedList<String>();
}
process:
for (ClassFileInfo c : infos) {
final String packageName = c.getPackageName();
subClasses.add(name);
}
final Callbacks.SourceFileNameLookup sourceNameLookup = new Callbacks.SourceFileNameLookup() {
public String get(final String sourceAttribute) {
public String getFullName() {
return fullName;
}
assert (sourceAttribute != null);
public String getPackageName() {
return packageName;
}
final String className = basename(sourceAttribute, ".java");
final List<String> candidates = readFiles.get(className);
public String toString() {
final StringBuilder builder = new StringBuilder();
assert (candidates != null);
builder.append(" Root: ").append(fullName).append(", package ").append(packageName).append("\n");
builder.append(" Subclasses:");
if (candidates.size() == 1) {
return candidates.get(0);
}
if (subClasses != null)
for (String s : subClasses) {
builder.append(" ").append(s);
for (String r : candidates) {
if (new PackageNameSelector().get(r).equals(packageName)) {
return r;
}
}
builder.append(".\n");
assert (false);
return builder.toString();
return null;
}
};
c.associate(sourceNameLookup);
}
}
public void associate(final Callbacks.SourceFileNameLookup sourceFileNameLookup) {
if (callback != null) {
callback.associate(fullName, sourceFileNameLookup, getClassReader(fullName));
/*
System.out.println("Written files info:");
if (subClasses != null) {
for (String s : subClasses) {
callback.associate(s, sourceFileNameLookup, getClassReader(s));
}
}
}
for (Map.Entry<String, List<ClassFileInfo>> e : writtenFiles.entrySet()) {
final String className = e.getKey();
final List<ClassFileInfo> infos = e.getValue();
System.out.println(" Class name: " + className);
System.out.println(" Class file info(s): ");
for (ClassFileInfo c : infos) {
System.out.println(c.toString());
}
}
System.out.println("End.");
System.out.println("Read files info:");
for (Map.Entry<String, List<String>> e : readFiles.entrySet()) {
final String className = e.getKey();
final List<String> files = e.getValue();
System.out.println(" Class name: " + className);
System.out.print(" Files:");
for (String file : files) {
System.out.print(" " + file);
}
System.out.println(".");
}
System.out.println("End.");
*/
}
}
private String extractPackage(final String s) {
if (s.length() < stripLength) return "";
return s.substring(stripLength);
}
public void messageLogged(BuildEvent event) {
final String m = event.getMessage();
final Matcher writtenMatcher = written.matcher(m);
final Matcher readMatcher = read.matcher(m);
if (writtenMatcher.matches()) {
final String fullName = writtenMatcher.group(1);
final File file = new File(fullName);
final String classFileName = file.getName();
final String packageName = extractPackage(fullName.substring(0, fullName.length() - classFileName.length() - 1));
String className = basename(classFileName, ".class");
boolean subClass = false;
final int i = className.indexOf('$');
if (i >= 0) {
className = className.substring(0, i);
subClass = true;
}
List<ClassFileInfo> info = writtenFiles.get(className);
if (info == null) {
info = new LinkedList<ClassFileInfo>();
writtenFiles.put(className, info);
}
boolean updated = false;
for (ClassFileInfo ci : info) {
if (subClass) {
if (ci.getPackageName().equals(packageName)) {
ci.attachSubClass(fullName);
updated = true;
}
}
}
public AntListener(final String targetFolder, final List<String> sourceRoots, final Callbacks.Backend callback) {
this.targetFolder = targetFolder;
this.sourceRoots = sourceRoots;
this.callback = callback;
stripLength = targetFolder.length() + 1;
}
public void buildStarted(BuildEvent event) {
//To change body of implemented methods use File | Settings | File Templates.
}
public void buildFinished(BuildEvent event) {
//To change body of implemented methods use File | Settings | File Templates.
}
public void targetStarted(BuildEvent event) {
//To change body of implemented methods use File | Settings | File Templates.
}
public void targetFinished(BuildEvent event) {
//To change body of implemented methods use File | Settings | File Templates.
}
public void taskStarted(BuildEvent event) {
}
public void taskFinished(BuildEvent event) {
if (event.getTask().getTaskName().equals("javac")) {
for (Map.Entry<String, List<ClassFileInfo>> e : writtenFiles.entrySet()) {
final String className = e.getKey();
final List<ClassFileInfo> infos = e.getValue();
final List<String> read = readFiles.get(className);
if (infos.size() == 1 && read != null && read.size() == 1) {
infos.get(0).associate(Callbacks.getDefaultLookup(read.get(0)));
continue;
}
process:
for (ClassFileInfo c : infos) {
final String packageName = c.getPackageName();
final Callbacks.SourceFileNameLookup sourceNameLookup = new Callbacks.SourceFileNameLookup() {
public String get(final String sourceAttribute) {
assert (sourceAttribute != null);
final String className = basename(sourceAttribute, ".java");
final List<String> candidates = readFiles.get(className);
assert (candidates != null);
if (candidates.size() == 1) {
return candidates.get(0);
}
for (String r : candidates) {
if (new PackageNameSelector().get(r).equals(packageName)) {
return r;
}
}
assert (false);
return null;
}
};
c.associate(sourceNameLookup);
}
}
/*
System.out.println("Written files info:");
for (Map.Entry<String, List<ClassFileInfo>> e : writtenFiles.entrySet()) {
final String className = e.getKey();
final List<ClassFileInfo> infos = e.getValue();
System.out.println(" Class name: " + className);
System.out.println(" Class file info(s): ");
for (ClassFileInfo c : infos) {
System.out.println(c.toString());
}
}
System.out.println("End.");
System.out.println("Read files info:");
for (Map.Entry<String, List<String>> e : readFiles.entrySet()) {
final String className = e.getKey();
final List<String> files = e.getValue();
System.out.println(" Class name: " + className);
System.out.print(" Files:");
for (String file : files) {
System.out.print(" " + file);
}
System.out.println(".");
}
System.out.println("End.");
*/
else {
if (ci.getFullName().equals(fullName)) {
updated = true;
break;
}
}
}
}
private String extractPackage(final String s) {
if (s.length() < stripLength)
return "";
return s.substring(stripLength);
}
public void messageLogged(BuildEvent event) {
final String m = event.getMessage();
final Matcher writtenMatcher = written.matcher(m);
final Matcher readMatcher = read.matcher(m);
if (writtenMatcher.matches()) {
final String fullName = writtenMatcher.group(1);
final File file = new File(fullName);
final String classFileName = file.getName();
final String packageName = extractPackage(fullName.substring(0, fullName.length() - classFileName.length() - 1));
String className = basename(classFileName, ".class");
boolean subClass = false;
final int i = className.indexOf('$');
if (i >= 0) {
className = className.substring(0, i);
subClass = true;
}
List<ClassFileInfo> info = writtenFiles.get(className);
if (info == null) {
info = new LinkedList<ClassFileInfo>();
writtenFiles.put(className, info);
}
boolean updated = false;
for (ClassFileInfo ci : info) {
if (subClass) {
if (ci.getPackageName().equals(packageName)) {
ci.attachSubClass(fullName);
updated = true;
}
} else {
if (ci.getFullName().equals(fullName)) {
updated = true;
break;
}
}
}
if (!updated) {
if (subClass) {
final ClassFileInfo c = new ClassFileInfo(targetFolder + File.separator + packageName + File.separator + className + ".class", packageName);
c.attachSubClass(fullName);
info.add(c);
} else {
info.add(new ClassFileInfo(fullName, packageName));
}
}
if (!updated) {
if (subClass) {
final ClassFileInfo c =
new ClassFileInfo(targetFolder + File.separator + packageName + File.separator + className + ".class", packageName);
c.attachSubClass(fullName);
info.add(c);
}
if (readMatcher.matches()) {
final String fullName = readMatcher.group(1);
final File file = new File(fullName);
final String sourceFileName = file.getName();
final String className = basename(sourceFileName, ".java");
List<String> files = readFiles.get(className);
if (files == null) {
files = new LinkedList<String>();
readFiles.put(className, files);
}
files.add(fullName);
else {
info.add(new ClassFileInfo(fullName, packageName));
}
}
}
if (readMatcher.matches()) {
final String fullName = readMatcher.group(1);
final File file = new File(fullName);
final String sourceFileName = file.getName();
final String className = basename(sourceFileName, ".java");
List<String> files = readFiles.get(className);
if (files == null) {
files = new LinkedList<String>();
readFiles.put(className, files);
}
files.add(fullName);
}
}
}
@@ -1,35 +0,0 @@
package org.jetbrains.ether.dependencyView;
import org.jetbrains.ether.Pair;
import org.objectweb.asm.ClassReader;
import java.util.Collection;
import java.util.Set;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 28.01.11
* Time: 15:55
* To change this template use File | Settings | File Templates.
*/
public class Callbacks {
public interface SourceFileNameLookup {
String get(String sourceAttribute);
}
public static SourceFileNameLookup getDefaultLookup(final String name) {
return new SourceFileNameLookup() {
public String get(final String sourceAttribute) {
return name;
}
};
}
public interface Backend {
Collection<StringCache.S> getClassFiles();
void associate(String classFileName, SourceFileNameLookup sourceLookup, ClassReader cr);
void associate(Set<Pair<ClassRepr,Set<StringCache.S>>> classes, Pair<UsageRepr.Cluster, Set<UsageRepr.Usage>> usages, String sourceFileName);
void associateForm(StringCache.S formName, StringCache.S className);
}
}
@@ -1,115 +0,0 @@
package org.jetbrains.ether.dependencyView;
import org.jetbrains.ether.Pair;
import java.util.*;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 01.03.11
* Time: 17:39
* To change this template use File | Settings | File Templates.
*/
public abstract class Difference {
public static final int NONE = 0;
public static final int ACCESS = 1;
public static final int TYPE = 2;
public static final int VALUE = 4;
public static final int SIGNATURE = 8;
public static final int SUPERCLASS = 16;
public interface Specifier<T> {
public Collection<T> added();
public Collection<T> removed();
public Collection<Pair<T, Difference>> changed();
public boolean unchanged();
}
public static <T> Specifier<T> make(final Set<T> past, final Set<T> now) {
if (past == null) {
final Collection<T> removed = new HashSet<T>();
final Collection<Pair<T, Difference>> changed = new HashSet<Pair<T, Difference>>();
return new Specifier<T>() {
public Collection<T> added() {
return now;
}
public Collection<T> removed() {
return removed;
}
public Collection<Pair<T, Difference>> changed() {
return changed;
}
public boolean unchanged() {
return false;
}
};
}
final Set<T> added = new HashSet<T>(now);
added.removeAll(past);
final Set<T> removed = new HashSet<T>(past);
removed.removeAll(now);
final Set<Pair<T, Difference>> changed = new HashSet<Pair<T, Difference>>();
final Set<T> intersect = new HashSet<T>(past);
final Map<T, T> nowMap = new HashMap<T, T>();
for (T s : now) {
if (intersect.contains(s)) {
nowMap.put(s, s);
}
}
intersect.retainAll(now);
for (T x : intersect) {
final T y = nowMap.get(x);
if (x instanceof Proto) {
final Proto px = (Proto) x;
final Proto py = (Proto) y;
final Difference diff = py.difference(px);
if (!diff.no()) {
changed.add(new Pair<T, Difference>(x, diff));
}
}
}
return new Specifier<T>() {
public Collection<T> added() {
return added;
}
public Collection<T> removed() {
return removed;
}
public Collection<Pair<T, Difference>> changed() {
return changed;
}
public boolean unchanged() {
return changed.isEmpty() && added.isEmpty() && removed.isEmpty();
}
};
}
public abstract int base();
public abstract boolean no();
public abstract int addedModifiers ();
public abstract int removedModifiers ();
public abstract boolean packageLocalOn();
}
@@ -1,58 +0,0 @@
package org.jetbrains.ether.dependencyView;
import org.jetbrains.ether.RW;
import org.objectweb.asm.Type;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.util.Set;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 01.02.11
* Time: 4:56
* To change this template use File | Settings | File Templates.
*/
public class FieldRepr extends ProtoMember {
public void updateClassUsages(final Set<UsageRepr.Usage> s) {
type.updateClassUsages(s);
}
public FieldRepr(final int a, final String n, final String d, final String s, final Object v) {
super(a, s, StringCache.get(n), TypeRepr.getType(d), v);
}
public FieldRepr(final BufferedReader r) {
super(r);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final FieldRepr fieldRepr = (FieldRepr) o;
return name.equals(fieldRepr.name);
}
@Override
public int hashCode() {
return 31 * name.hashCode();
}
public static RW.Reader<FieldRepr> reader = new RW.Reader<FieldRepr>() {
public FieldRepr read(final BufferedReader r) {
return new FieldRepr(r);
}
};
public UsageRepr.Usage createUsage (final StringCache.S owner) {
return UsageRepr.createFieldUsage(name.value, owner.value, type.getDescr());
}
public UsageRepr.Usage createAssignUsage (final StringCache.S owner) {
return UsageRepr.createFieldAssignUsage(name.value, owner.value, type.getDescr());
}
}
@@ -1,132 +0,0 @@
package org.jetbrains.ether.dependencyView;
import java.util.*;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 08.03.11
* Time: 15:38
* To change this template use File | Settings | File Templates.
*/
public class FoxyMap<K, V> implements Map<K, Object> {
public interface CollectionConstructor<X> {
public Collection<X> create();
}
private final Map<K, Object> map = new HashMap<K, Object>();
private final CollectionConstructor<V> constr;
public FoxyMap(final CollectionConstructor<V> c) {
constr = c;
}
public int size() {
return map.size();
}
public boolean isEmpty() {
return map.isEmpty();
}
public boolean containsKey(final Object key) {
return map.containsKey(key);
}
public boolean containsValue(final Object value) {
return map.containsValue(value);
}
public Object get(final Object key) {
return map.get(key);
}
public Collection<V> foxyGet(final K key) {
final Object c = get(key);
if (c == null) {
return null;
}
if (c instanceof Collection) {
return (Collection) c;
}
final Collection<V> l = constr.create();
l.add((V) c);
return l;
}
public Object put(final K key, final Object value) {
final Object c = get(key);
if (c == null) {
map.put(key, value);
} else {
if (c instanceof Collection) {
if (value instanceof Collection)
((Collection) c).addAll((Collection) value);
else
((Collection) c).add(value);
} else {
final Collection d = constr.create();
d.add(c);
if (value instanceof Collection)
d.addAll((Collection) value);
else
d.add(value);
map.put(key, d);
}
}
return c;
}
public Object remove(final Object key) {
return map.remove(key);
}
public void putAll(Map<? extends K, ? extends Object> m) {
for (Entry<? extends K, ? extends Object> e : m.entrySet()) {
remove(e.getKey());
put(e.getKey(), e.getValue());
}
}
public void clear() {
map.clear();
}
public Set<K> keySet() {
return map.keySet();
}
public Collection<Object> values() {
final List l = new LinkedList();
for (Object value : map.values()) {
if (value instanceof Collection) {
l.addAll((Collection) value);
} else {
l.add(value);
}
}
return l;
}
public Collection<V> foxyValues() {
return (Collection<V>) values();
}
public Set<Entry<K, Object>> entrySet() {
return map.entrySet();
}
}
@@ -1,148 +0,0 @@
package org.jetbrains.ether.dependencyView;
import org.jetbrains.ether.RW;
import org.objectweb.asm.Type;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 01.02.11
* Time: 5:03
* To change this template use File | Settings | File Templates.
*/
public class MethodRepr extends ProtoMember {
private static TypeRepr.AbstractType[] dummyAbstractType = new TypeRepr.AbstractType[0];
public final TypeRepr.AbstractType[] argumentTypes;
public final Set<TypeRepr.AbstractType> exceptions;
public abstract class Diff extends Difference {
public abstract Specifier<TypeRepr.AbstractType> exceptions();
public abstract boolean defaultAdded ();
public abstract boolean defaultRemoved ();
}
@Override
public Difference difference(final Proto past) {
final Difference diff = super.difference(past);
final Difference.Specifier<TypeRepr.AbstractType> excs = Difference.make(((MethodRepr) past).exceptions, exceptions);
return new Diff() {
@Override
public int addedModifiers() {
return diff.addedModifiers();
}
@Override
public int removedModifiers() {
return diff.removedModifiers();
}
@Override
public boolean no() {
return base() == NONE && !defaultAdded() && !defaultRemoved() && excs.unchanged();
}
@Override
public boolean defaultAdded() {
return hasValue() && !((MethodRepr) past).hasValue();
}
@Override
public boolean defaultRemoved() {
return !hasValue() && ((MethodRepr) past).hasValue();
}
@Override
public Specifier<TypeRepr.AbstractType> exceptions() {
return excs;
}
@Override
public int base() {
return diff.base();
}
@Override
public boolean packageLocalOn() {
return diff.packageLocalOn();
}
};
}
public void updateClassUsages(final Set<UsageRepr.Usage> s) {
type.updateClassUsages(s);
for (int i = 0; i < argumentTypes.length; i++) {
argumentTypes[i].updateClassUsages(s);
}
if (exceptions != null)
for (TypeRepr.AbstractType typ : exceptions) {
typ.updateClassUsages(s);
}
}
public MethodRepr(final int a, final String n, final String s, final String d, final String[] e, final Object value) {
super(a, s, StringCache.get(n), TypeRepr.getType(Type.getReturnType(d)), value);
exceptions = (Set<TypeRepr.AbstractType>) TypeRepr.createClassType(e, new HashSet<TypeRepr.AbstractType>());
argumentTypes = TypeRepr.getType(Type.getArgumentTypes(d));
}
public MethodRepr(final BufferedReader r) {
super(r);
argumentTypes = RW.readMany(r, TypeRepr.reader, new ArrayList<TypeRepr.AbstractType>()).toArray(dummyAbstractType);
exceptions = (Set<TypeRepr.AbstractType>) RW.readMany(r, TypeRepr.reader, new HashSet<TypeRepr.AbstractType>());
}
public void write(final BufferedWriter w) {
super.write(w);
RW.writeln(w, argumentTypes, TypeRepr.fromAbstractType);
RW.writeln(w, exceptions);
}
public static RW.Reader<MethodRepr> reader = new RW.Reader<MethodRepr>() {
public MethodRepr read(final BufferedReader r) {
return new MethodRepr(r);
}
};
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final MethodRepr that = (MethodRepr) o;
return name .equals(that.name ) &&
type .equals(that.type) &&
Arrays.equals(argumentTypes, that.argumentTypes);
}
@Override
public int hashCode() {
return 31 * (31 * Arrays.hashCode(argumentTypes) + type.hashCode()) + name.hashCode();
}
public UsageRepr.Usage createUsage (final StringCache.S owner) {
final StringBuilder buf = new StringBuilder();
buf.append("(");
for (TypeRepr.AbstractType t : argumentTypes) {
buf.append(t.getDescr());
}
buf.append(")");
buf.append(type.getDescr());
return UsageRepr.createMethodUsage(name.value, owner.value, buf.toString());
}
}
@@ -1,269 +0,0 @@
package org.jetbrains.ether.dependencyView;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 02.04.11
* Time: 17:12
* To change this template use File | Settings | File Templates.
*/
public class PackageNameSelector {
String buffer = null;
int index = 0;
BufferedReader reader = null;
char saved;
boolean isSaved = false;
private void read() {
try {
buffer = reader.readLine();
index = 0;
} catch (IOException e) {
e.printStackTrace();
}
}
private char get() {
if (buffer == null) {
return 0;
} else if (index == buffer.length()) {
read();
return '\r';
}
final char c = buffer.charAt(index++);
if (c == 0) {
return ' ';
}
return c;
}
private char symbol() {
if (isSaved) {
isSaved = false;
return saved;
}
final char c = get();
switch (c) {
case '"': {
loop:
while (true) {
switch (get()) {
case 0:
return 0;
case '"':
case '\r':
break loop;
case '\\':
switch (get()) {
case 0:
return 0;
case '\r':
break loop;
}
}
}
return ' ';
}
case '\'': {
loop:
while (true) {
switch (get()) {
case 0:
return 0;
case '\'':
case '\r':
break loop;
case '\\':
switch (get()) {
case 0:
return 0;
case '\r':
break loop;
}
}
}
return ' ';
}
case '/': {
final char d = get();
if (d == '/') {
loop:
while (true) {
switch (get()) {
case 0:
return 0;
case '\r':
break loop;
}
}
return ' ';
} else if (d == '*') {
loop:
while (true) {
switch (get()) {
case 0:
return 0;
case '*':
inner:
while (true) {
switch (get()) {
case 0:
return 0;
case '/':
break loop;
case '*':
continue;
default:
break inner;
}
}
}
}
return ' ';
} else {
saved = d;
isSaved = true;
return c;
}
}
default: {
return c;
}
}
}
private void open(final String fileName) {
try {
reader = new BufferedReader(new FileReader(new File(fileName)));
read();
} catch (IOException e) {
e.printStackTrace();
}
}
private void close() {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private String parse() {
final StringBuilder b = new StringBuilder();
int state = 0;
while (true) {
final char c = symbol();
switch (c) {
case 0: {
return "";
}
default: {
switch (state) {
case 0: // Initial state
if (Character.isLetter(c)) {
b.append(c);
state = 1;
}
break;
case 1: // Identifier
if (Character.isLetter(c)) {
b.append(c);
} else if (Character.isWhitespace(c)) {
final String ident = b.toString();
b.setLength(0);
if (ident.equals("package")) {
state = 2;
} else if (ident.equals("import")) {
return "";
}
} else {
state = 0;
}
break;
case 2: // Post "package<whitespace>
if (Character.isWhitespace(c)) {
} else if (c == '.') {
b.append(File.separatorChar);
} else if (c == ';') {
return b.toString();
} else {
b.append(c);
}
}
}
}
}
}
public String get(final String fileName) {
open(fileName);
final String result = parse();
close();
return result;
}
//
// final private static String whiteSpacePattern = "(/\\*.*?\\*/|//[^\\r\\n\\f\\x0B]*)";
// final private static String stringLiteralPattern = "(\"([^\\\\\"]|\\\\.)*\")";
// final private static String charLiteralPattern = "('([^\\\\']|\\\\.)*')";
// final private static Pattern skipPattern = Pattern.compile(whiteSpacePattern + "|" + stringLiteralPattern + "|" + charLiteralPattern, Pattern.DOTALL);
// final private static Pattern packagePattern = Pattern.compile("\\bpackage\\s+([^;]+);");
// final private static Pattern spacePattern = Pattern.compile("\\s+");
// final private static Pattern dotPattern = Pattern.compile("\\.");
//
// public static String get (final String fileName) throws Exception {
// //try {
// final FileChannel channel = new FileInputStream(fileName).getChannel();
//
// final Matcher skipMatcher = skipPattern.matcher(Charset.forName("ISO-8859-1").newDecoder().decode(channel.map(FileChannel.MapMode.READ_ONLY, 0, (int) channel.size())));
// final String cleared = skipMatcher.replaceAll(" ");
//
// System.out.println(cleared);
//
// final Matcher selecting = packagePattern.matcher(cleared);
//
// if (selecting.find()) {
// final String qualifiedName = selecting.group(1);
// final Matcher spaceRemover = spacePattern.matcher(qualifiedName);
// final String spaceRemoved = spaceRemover.replaceAll("");
// final Matcher dotReplacer = dotPattern.matcher(spaceRemoved);
//
// return dotReplacer.replaceAll("/");
// } else {
// return null;
// }
// //} catch (IOException e) {
// // e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
//
// // return null;
// //}
// }
}
@@ -1,89 +0,0 @@
package org.jetbrains.ether.dependencyView;
import groovyjarjarasm.asm.Opcodes;
import org.jetbrains.ether.RW;
import java.io.BufferedReader;
import java.io.BufferedWriter;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 01.03.11
* Time: 17:57
* To change this template use File | Settings | File Templates.
*/
public abstract class Proto implements RW.Writable {
public final int access;
public final StringCache.S signature;
public final StringCache.S name;
protected Proto(final int access, final String signature, final StringCache.S name) {
this.access = access;
this.signature = StringCache.get(signature != null ? signature : "");
this.name = name;
}
protected Proto (final BufferedReader r) {
access = RW.readInt (r);
signature = StringCache.get(RW.readString(r));
name = StringCache.get(RW.readString(r));
}
public void write (final BufferedWriter w) {
RW.writeln(w, Integer.toString (access));
RW.writeln(w, signature.value);
RW.writeln(w, name.value);
}
public Difference difference (final Proto past) {
int diff = Difference.NONE;
if (past.access != access) {
diff |= Difference.ACCESS;
}
if (! past.signature.equals(signature)) {
diff |= Difference.SIGNATURE;
}
final int base = diff;
return new Difference() {
@Override
public int base() {
return base;
}
@Override
public boolean no() {
return base == Difference.NONE;
}
@Override
public int addedModifiers() {
return ~past.access & access;
}
@Override
public int removedModifiers() {
return ~access & past.access;
}
@Override
public boolean packageLocalOn() {
return
((past.access & Opcodes.ACC_PRIVATE) != 0 ||
(past.access & Opcodes.ACC_PUBLIC) != 0 ||
(past.access & Opcodes.ACC_PROTECTED) != 0
)
&&
((access & Opcodes.ACC_PRIVATE) == 0 &&
(access & Opcodes.ACC_PROTECTED) == 0 &&
(access & Opcodes.ACC_PUBLIC) == 0);
}
};
}
}
@@ -1,142 +0,0 @@
package org.jetbrains.ether.dependencyView;
import org.jetbrains.ether.RW;
import java.io.BufferedReader;
import java.io.BufferedWriter;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 07.03.11
* Time: 19:54
* To change this template use File | Settings | File Templates.
*/
public abstract class ProtoMember extends Proto {
public final TypeRepr.AbstractType type;
public final Object value;
public boolean hasValue () {
return value != null;
}
protected ProtoMember(final int access, final String signature, final StringCache.S name, final TypeRepr.AbstractType t, final Object value) {
super(access, signature, name);
this.type = t;
this.value = value;
}
private static Object readTyped(final BufferedReader r, final String tag) {
if (tag.equals("string")) {
return RW.readEncodedString(r);
}
if (tag.equals("none")) {
return null;
}
final String val = RW.readString(r);
if (tag.equals("integer"))
return Integer.parseInt(val);
if (tag.equals("long"))
return Long.parseLong(val);
if (tag.equals("float"))
return Float.parseFloat(val);
if (tag.equals("double"))
return Double.parseDouble(val);
return null;
}
protected ProtoMember(final BufferedReader r) {
super(r);
type = TypeRepr.reader.read(r);
value = readTyped(r, RW.readString(r));
}
public void write(final BufferedWriter w) {
super.write(w);
type.write(w);
if (value instanceof String) {
RW.writeln(w, "string");
RW.writeEncodedString(w, (String) value);
} else if (value instanceof Integer) {
RW.writeln(w, "integer");
RW.writeln(w, value.toString());
} else if (value instanceof Long) {
RW.writeln(w, "long");
RW.writeln(w, value.toString());
} else if (value instanceof Float) {
RW.writeln(w, "float");
RW.writeln(w, value.toString());
} else if (value instanceof Double) {
RW.writeln(w, "double");
RW.writeln(w, value.toString());
} else {
RW.writeln(w, "none");
}
}
public Difference difference(final Proto past) {
final ProtoMember m = (ProtoMember) past;
final Difference diff = super.difference(past);
int base = diff.base();
if (!m.type.equals(type)) {
base |= Difference.TYPE;
}
switch ((value == null ? 0 : 1) + (m.value == null ? 0 : 2)) {
case 3:
if (!value.equals(m.value)) {
base |= Difference.VALUE;
}
break;
case 2:
base |= Difference.VALUE;
break;
case 1:
base |= Difference.VALUE;
break;
case 0:
break;
}
final int newBase = base;
return new Difference () {
@Override
public int base() {
return newBase;
}
@Override
public boolean no() {
return newBase == Difference.NONE && diff.no();
}
@Override
public int addedModifiers() {
return diff.addedModifiers();
}
@Override
public int removedModifiers() {
return diff.removedModifiers();
}
@Override
public boolean packageLocalOn() {
return diff.packageLocalOn();
}
};
}
}
@@ -1,113 +0,0 @@
package org.jetbrains.ether.dependencyView;
import org.jetbrains.ether.RW;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 14.02.11
* Time: 2:03
* To change this template use File | Settings | File Templates.
*/
public class StringCache {
public static class S implements Comparable<S>, RW.Writable {
public final int index;
public final String value;
private S(final int i, final String v) {
index = i;
value = v;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
S s = (S) o;
if (index != s.index) return false;
return true;
}
@Override
public int hashCode() {
return index;
}
public int compareTo(S o) {
return index - o.index;
}
public void write(BufferedWriter w) {
RW.writeln(w, value);
}
public static final RW.Reader<S> reader = new RW.Reader<S>() {
public S read(final BufferedReader r) {
final String s = RW.readString(r);
return StringCache.get(s);
}
};
public String toString () {
return value;
}
}
private static final Map<String, S> map = new HashMap<String, S>();
private static int index = 0;
public static S get(final String s) {
// if (s == null)
// return null;
//
S r = map.get(s);
if (r == null) {
r = new S(index++, s);
map.put(s, r);
}
return r;
}
public static S[] get(final String[] s) {
if (s == null) {
return null;
}
final S[] r = new S[s.length];
for (int i = 0; i < r.length; i++)
r[i] = get(s[i]);
return r;
}
public static RW.ToWritable<S> fromS = new RW.ToWritable<S>() {
public RW.Writable convert(S x) {
return RW.fromString.convert(x.value);
}
};
public static RW.Reader<S> reader = new RW.Reader<S>() {
public S read(final BufferedReader r) {
try {
return get(r.readLine());
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
};
}
@@ -1,316 +0,0 @@
package org.jetbrains.ether.dependencyView;
import org.jetbrains.ether.RW;
import org.objectweb.asm.Type;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.util.*;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 14.02.11
* Time: 3:54
* To change this template use File | Settings | File Templates.
*/
public class TypeRepr {
public static abstract class AbstractType implements RW.Writable {
public abstract void updateClassUsages(Set<UsageRepr.Usage> s);
public abstract String getDescr();
}
public static class PrimitiveType extends AbstractType {
public final StringCache.S type;
@Override
public String getDescr() {
return type.value;
}
@Override
public void updateClassUsages(Set<UsageRepr.Usage> s) {
}
public void write(final BufferedWriter w) {
RW.writeln(w, "primitive");
RW.writeln(w, type.value);
}
PrimitiveType(final String type) {
this.type = StringCache.get(type);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final PrimitiveType that = (PrimitiveType) o;
return type.equals(that.type);
}
@Override
public int hashCode() {
return type.hashCode();
}
}
public static class ArrayType extends AbstractType {
public final AbstractType elementType;
public AbstractType getDeepElementType() {
AbstractType current = this;
while (current instanceof ArrayType) {
current = ((ArrayType) current).elementType;
}
return current;
}
@Override
public String getDescr() {
return "[" + elementType.getDescr();
}
@Override
public void updateClassUsages(Set<UsageRepr.Usage> s) {
elementType.updateClassUsages(s);
}
ArrayType(final AbstractType elementType) {
this.elementType = elementType;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final ArrayType arrayType = (ArrayType) o;
return elementType.equals(arrayType.elementType);
}
@Override
public int hashCode() {
return elementType.hashCode();
}
public void write(BufferedWriter w) {
RW.writeln(w, "array");
elementType.write(w);
}
}
public static class ClassType extends AbstractType {
public final StringCache.S className;
public final AbstractType[] typeArgs;
@Override
public String getDescr() {
return "L" + className.value + ";";
}
@Override
public void updateClassUsages(Set<UsageRepr.Usage> s) {
s.add(UsageRepr.createClassUsage(className));
}
ClassType(final BufferedReader r){
className = StringCache.get(RW.readString(r));
final Collection<AbstractType> args = RW.readMany(r, reader, new LinkedList<AbstractType>());
typeArgs = args.toArray(new AbstractType[args.size()]);
}
ClassType(final String className) {
this.className = StringCache.get(className);
typeArgs = new AbstractType[0];
}
ClassType(final StringCache.S className) {
this.className = className;
typeArgs = new AbstractType[0];
}
ClassType(final String className, final AbstractType[] typeArgs) {
this.className = StringCache.get(className);
this.typeArgs = typeArgs;
}
ClassType(final StringCache.S className, final AbstractType[] typeArgs) {
this.className = className;
this.typeArgs = typeArgs;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final ClassType classType = (ClassType) o;
if (className != null ? !className.equals(classType.className) : classType.className != null) return false;
if (!Arrays.equals(typeArgs, classType.typeArgs)) return false;
return true;
}
@Override
public int hashCode() {
int result = className != null ? className.hashCode() : 0;
result = 31 * result + (typeArgs != null ? Arrays.hashCode(typeArgs) : 0);
return result;
}
public void write(BufferedWriter w) {
RW.writeln(w, "class");
RW.writeln(w, className.value);
RW.writeln(w, typeArgs);
}
}
public static ClassType createClassType(final String s) {
return (ClassType) getType(new ClassType(s));
}
public static ClassType createClassType(final StringCache.S s) {
return (ClassType) getType(new ClassType(s));
}
public static ClassType[] createClassType(final String[] s) {
if (s == null) {
return null;
}
final ClassType[] types = new ClassType[s.length];
for (int i = 0; i < types.length; i++) {
types[i] = createClassType(s[i]);
}
return types;
}
public static Collection<AbstractType> createClassType(final String[] s, final Collection<AbstractType> acc) {
if (s != null) {
for (String ss : s) {
acc.add(createClassType(ss));
}
}
return acc;
}
public static Collection<AbstractType> createClassType(final Collection<String> s, final Collection<AbstractType> acc) {
if (s != null) {
for (String ss : s) {
acc.add(createClassType(ss));
}
}
return acc;
}
private static final Map<AbstractType, AbstractType> map = new HashMap<AbstractType, AbstractType>();
private static AbstractType getType(final AbstractType t) {
final AbstractType r = map.get(t);
if (r != null) {
return r;
}
map.put(t, t);
return t;
}
public static AbstractType getType(final String descr) {
final Type t = Type.getType(descr);
switch (t.getSort()) {
case Type.OBJECT:
return getType(new ClassType(t.getClassName()));
case Type.ARRAY:
return getType(new ArrayType(getType(t.getElementType())));
default:
return getType(new PrimitiveType(descr));
}
}
public static AbstractType getType(final Type t) {
return getType(t.getDescriptor());
}
public static AbstractType[] getType(final Type[] t) {
final AbstractType[] r = new AbstractType[t.length];
for (int i = 0; i < r.length; i++)
r[i] = getType(t[i]);
return r;
}
public static AbstractType[] getType(final String[] t) {
if (t == null) {
return null;
}
final AbstractType[] types = new AbstractType[t.length];
for (int i = 0; i < types.length; i++) {
types[i] = getType(Type.getType(t[i]));
}
return types;
}
public static RW.Reader<AbstractType> reader = new RW.Reader<AbstractType>() {
public AbstractType read(final BufferedReader r) {
AbstractType elementType = null;
int level = 0;
while (true) {
final String tag = RW.readString(r);
if (tag.equals("primitive")) {
elementType = getType(new PrimitiveType(RW.readString(r)));
break;
}
if (tag.equals("class")) {
elementType = getType(new ClassType(r));
break;
}
if (tag.equals("array")) {
level++;
}
}
for (int i = 0; i < level; i++) {
elementType = getType(new ArrayType(elementType));
}
return elementType;
}
};
public static RW.ToWritable<AbstractType> fromAbstractType = new RW.ToWritable<AbstractType>() {
public RW.Writable convert(final AbstractType x) {
return new RW.Writable() {
public void write(final BufferedWriter w) {
x.write(w);
}
};
}
};
}
@@ -1,503 +0,0 @@
package org.jetbrains.ether.dependencyView;
import org.jetbrains.ether.RW;
import org.objectweb.asm.Type;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.lang.annotation.ElementType;
import java.util.*;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 14.02.11
* Time: 5:11
* To change this template use File | Settings | File Templates.
*/
public class UsageRepr {
private final static TypeRepr.AbstractType[] dummyAbstractType = new TypeRepr.AbstractType[0];
private final static Map<Usage, Usage> map = new HashMap<Usage, Usage>();
private static Usage getUsage(final Usage u) {
final Usage r = map.get(u);
if (r == null) {
map.put(u, u);
return u;
}
return r;
}
public static class Cluster implements RW.Writable {
final Set<Usage> usages = new HashSet<Usage>();
final Map<Usage, Set<StringCache.S>> residentialMap = new HashMap<Usage, Set<StringCache.S>>();
public Cluster() {
}
public Cluster(final BufferedReader r) {
final int size = RW.readInt(r);
for (int i = 0; i < size; i++) {
final Usage u = reader.read(r);
final Set<StringCache.S> s = (Set<StringCache.S>) RW.readMany(r, StringCache.reader, new HashSet<StringCache.S>());
usages.add(u);
residentialMap.put(u, s);
}
}
public void write(final BufferedWriter w) {
RW.writeln(w, Integer.toString(usages.size()));
for (Usage u : usages) {
u.write(w);
RW.writeln(w, residentialMap.get(u));
}
}
public void addUsage(final String residence, final Usage usage) {
final StringCache.S r = StringCache.get(residence);
Set<StringCache.S> s = residentialMap.get(usage);
if (s == null) {
s = new HashSet<StringCache.S>();
residentialMap.put(usage, s);
}
s.add(r);
usages.add(usage);
}
public Set<Usage> getUsages() {
return usages;
}
public Set<StringCache.S> getResidence(final Usage usage) {
return residentialMap.get(usage);
}
public void updateCluster(final Cluster c) {
usages.addAll(c.getUsages());
for (Map.Entry<Usage, Set<StringCache.S>> e : c.residentialMap.entrySet()) {
final Usage u = e.getKey();
final Set<StringCache.S> v = e.getValue();
final Set<StringCache.S> s = residentialMap.get(u);
if (s == null) {
residentialMap.put(u, v);
} else {
s.addAll(v);
}
}
}
public boolean isEmpty() {
return usages.isEmpty();
}
}
public static abstract class Usage implements RW.Writable {
public abstract StringCache.S getOwner();
}
public static abstract class FMUsage extends Usage {
public final StringCache.S name;
public final StringCache.S owner;
@Override
public StringCache.S getOwner() {
return owner;
}
protected FMUsage(final String n, final String o) {
name = StringCache.get(n);
owner = StringCache.get(o);
}
protected FMUsage(final BufferedReader r) {
name = StringCache.get(RW.readString(r));
owner = StringCache.get(RW.readString(r));
}
}
public static class FieldUsage extends FMUsage {
public final TypeRepr.AbstractType type;
private FieldUsage(final String n, final String o, final String d) {
super(n, o);
type = TypeRepr.getType(d);
}
private FieldUsage(final BufferedReader r) {
super(r);
type = TypeRepr.reader.read(r);
}
public void write(final BufferedWriter w) {
RW.writeln(w, "fieldUsage");
RW.writeln(w, name.value);
RW.writeln(w, owner.value);
type.write(w);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final FieldUsage that = (FieldUsage) o;
return type.equals(that.type) && name.equals(that.name) && owner.equals(that.owner);
}
@Override
public int hashCode() {
return 31 * (31 * type.hashCode() + (name.hashCode())) + owner.hashCode();
}
}
public static class FieldAssignUsage extends FieldUsage {
private FieldAssignUsage(final String n, final String o, final String d) {
super(n, o, d);
}
private FieldAssignUsage(final BufferedReader r) {
super(r);
}
public void write(final BufferedWriter w) {
RW.writeln(w, "fieldAssignUsage");
RW.writeln(w, name.value);
RW.writeln(w, owner.value);
type.write(w);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final FieldAssignUsage that = (FieldAssignUsage) o;
return type.equals(that.type) && name.equals(that.name) && owner.equals(that.owner);
}
@Override
public int hashCode() {
return super.hashCode() + 1;
}
}
public static class MethodUsage extends FMUsage {
public final TypeRepr.AbstractType[] argumentTypes;
public final TypeRepr.AbstractType returnType;
private MethodUsage(final String n, final String o, final String d) {
super(n, o);
argumentTypes = TypeRepr.getType(Type.getArgumentTypes(d));
returnType = TypeRepr.getType(Type.getReturnType(d));
}
private MethodUsage(final BufferedReader r) {
super(r);
argumentTypes = RW.readMany(r, TypeRepr.reader, new ArrayList<TypeRepr.AbstractType>()).toArray(dummyAbstractType);
returnType = TypeRepr.reader.read(r);
}
public void write(final BufferedWriter w) {
RW.writeln(w, "methodUsage");
RW.writeln(w, name.value);
RW.writeln(w, owner.value);
RW.writeln(w, argumentTypes, TypeRepr.fromAbstractType);
returnType.write(w);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final MethodUsage that = (MethodUsage) o;
if (!Arrays.equals(argumentTypes, that.argumentTypes)) return false;
if (returnType != null ? !returnType.equals(that.returnType) : that.returnType != null) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
if (owner != null ? !owner.equals(that.owner) : that.owner != null) return false;
return Arrays.equals(argumentTypes, that.argumentTypes) &&
returnType.equals(that.returnType) &&
name.equals(that.name) &&
owner.equals(that.owner);
}
@Override
public int hashCode() {
return ((31 * Arrays.hashCode(argumentTypes) + (returnType.hashCode())) * 31 + (name.hashCode())) * 31 + (owner.hashCode());
}
}
public static class ClassUsage extends Usage {
final StringCache.S className;
@Override
public StringCache.S getOwner() {
return className;
}
private ClassUsage(final String n) {
className = StringCache.get(n);
}
private ClassUsage(final StringCache.S n) {
className = n;
}
private ClassUsage(final BufferedReader r) {
className = StringCache.get(RW.readString(r));
}
private ClassUsage(final BufferedReader r, boolean b) {
super();
className = StringCache.get(RW.readString(r));
}
public void write(final BufferedWriter w) {
RW.writeln(w, "classUsage");
RW.writeln(w, className.value);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final ClassUsage that = (ClassUsage) o;
return className.equals(that.className);
}
@Override
public int hashCode() {
return className.hashCode();
}
}
public static class ClassExtendsUsage extends Usage {
protected final StringCache.S className;
@Override
public StringCache.S getOwner() {
return className;
}
public ClassExtendsUsage(final StringCache.S n) {
className = n;
}
public ClassExtendsUsage(final BufferedReader r) {
className = StringCache.get(RW.readString(r));
}
public void write(final BufferedWriter w) {
RW.writeln(w, "classExtendsUsage");
RW.writeln(w, className.value);
}
@Override
public int hashCode() {
return className.hashCode() + 1;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ClassExtendsUsage that = (ClassExtendsUsage) o;
if (!className.equals(that.className)) return false;
return true;
}
}
public static class ClassNewUsage extends ClassExtendsUsage {
public ClassNewUsage(StringCache.S n) {
super(n);
}
public ClassNewUsage(BufferedReader r) {
super(r);
}
public void write(final BufferedWriter w) {
RW.writeln(w, "classNewUsage");
RW.writeln(w, className.value);
}
@Override
public int hashCode() {
return className.hashCode() + 2;
}
}
public static class AnnotationUsage extends Usage {
public static final RW.Reader<ElementType> elementTypeReader = new RW.Reader<ElementType>() {
public ElementType read(final BufferedReader r) {
return ElementType.valueOf(RW.readString(r));
}
};
public static final RW.ToWritable<ElementType> elementTypeToWritable = new RW.ToWritable<ElementType>() {
public RW.Writable convert(final ElementType x) {
return new RW.Writable() {
public void write(final BufferedWriter w) {
RW.writeln(w, x.toString());
}
};
}
};
final TypeRepr.ClassType type;
final Collection<StringCache.S> usedArguments;
final Collection<ElementType> usedTargets;
public boolean satisfies(final Usage usage) {
if (usage instanceof AnnotationUsage) {
final AnnotationUsage annotationUsage = (AnnotationUsage) usage;
if (!type.equals(annotationUsage.type)) {
return false;
}
boolean argumentsSatisfy = false;
if (usedArguments != null) {
final Collection<StringCache.S> arguments = new HashSet<StringCache.S>(usedArguments);
arguments.removeAll(annotationUsage.usedArguments);
argumentsSatisfy = !arguments.isEmpty();
}
boolean targetsSatisfy = false;
if (usedTargets != null) {
final Collection<ElementType> targets = new HashSet<ElementType>(usedTargets);
targets.retainAll(annotationUsage.usedTargets);
targetsSatisfy = !targets.isEmpty();
}
return argumentsSatisfy || targetsSatisfy;
}
return false;
}
private AnnotationUsage(final TypeRepr.ClassType type, final Collection<StringCache.S> usedArguments, final Collection<ElementType> targets) {
this.type = type;
this.usedArguments = usedArguments;
this.usedTargets = targets;
}
private AnnotationUsage(final BufferedReader r) {
type = (TypeRepr.ClassType) TypeRepr.reader.read(r);
usedArguments = RW.readMany(r, StringCache.reader, new HashSet<StringCache.S>());
usedTargets = RW.readMany(r, elementTypeReader, new HashSet<ElementType>());
}
@Override
public StringCache.S getOwner() {
return type.className;
}
public void write(final BufferedWriter w) {
RW.writeln(w, "annotationUsage");
type.write(w);
RW.writeln(w, usedArguments);
RW.writeln(w, usedTargets, elementTypeToWritable);
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AnnotationUsage that = (AnnotationUsage) o;
if (usedArguments != null ? !usedArguments.equals(that.usedArguments) : that.usedArguments != null)
return false;
if (usedTargets != null ? !usedTargets.equals(that.usedTargets) : that.usedTargets != null) return false;
if (type != null ? !type.equals(that.type) : that.type != null) return false;
return true;
}
@Override
public int hashCode() {
int result = type != null ? type.hashCode() : 0;
result = 31 * result + (usedArguments != null ? usedArguments.hashCode() : 0);
result = 31 * result + (usedTargets != null ? usedTargets.hashCode() : 0);
return result;
}
}
public static Usage createFieldUsage(final String name, final String owner, final String descr) {
return getUsage(new FieldUsage(name, owner, descr));
}
public static Usage createFieldAssignUsage(final String name, final String owner, final String descr) {
return getUsage(new FieldAssignUsage(name, owner, descr));
}
public static Usage createMethodUsage(final String name, final String owner, final String descr) {
return getUsage(new MethodUsage(name, owner, descr));
}
public static Usage createClassUsage(final String name) {
return getUsage(new ClassUsage(name));
}
public static Usage createClassUsage(final StringCache.S name) {
return getUsage(new ClassUsage(name));
}
public static Usage createClassExtendsUsage(final StringCache.S name) {
return getUsage(new ClassExtendsUsage(name));
}
public static Usage createClassNewUsage(final StringCache.S name) {
return getUsage(new ClassNewUsage(name));
}
public static Usage createAnnotationUsage(final TypeRepr.ClassType type, final Collection<StringCache.S> usedArguments, final Collection<ElementType> targets) {
return getUsage(new AnnotationUsage(type, usedArguments, targets));
}
public static RW.Reader<Usage> reader = new RW.Reader<Usage>() {
public Usage read(final BufferedReader r) {
final String tag = RW.readString(r);
if (tag.equals("classUsage")) {
return getUsage(new ClassUsage(r));
} else if (tag.equals("fieldUsage")) {
return getUsage(new FieldUsage(r));
} else if (tag.equals("fieldAssignUsage")) {
return getUsage(new FieldAssignUsage(r));
} else if (tag.equals("methodUsage")) {
return getUsage(new MethodUsage(r));
} else if (tag.equals("classExtendsUsage")) {
return getUsage(new ClassExtendsUsage(r));
} else if (tag.equals("classNewUsage")) {
return getUsage(new ClassNewUsage(r));
} else return getUsage(new AnnotationUsage(r));
}
};
}
@@ -0,0 +1,26 @@
Request to make modules:
module DependencyUpdate
End of request
digraph X {
DependencyUpdate[label="DependencyUpdate"];
}
digraph X {
DependencyUpdate[label="DependencyUpdate"];
}
Propagated modules:
module DependencyUpdate
End of propagated
Cleaning output files:
out/production/DependencyUpdate/A.class
out/production/DependencyUpdate/E.class
End of files
Compiling files:
src/A.java
src/E.java
End of files
Cleaning output files:
out/production/DependencyUpdate/B.class
End of files
Compiling files:
src/B.java
End of files
@@ -0,0 +1 @@
dependencyUpdate
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
<resourceExtensions />
<wildcardResourcePatterns>
<entry name="?*.properties" />
<entry name="?*.xml" />
<entry name="?*.gif" />
<entry name="?*.png" />
<entry name="?*.jpeg" />
<entry name="?*.jpg" />
<entry name="?*.html" />
<entry name="?*.dtd" />
<entry name="?*.tld" />
<entry name="?*.ftl" />
</wildcardResourcePatterns>
<annotationProcessing enabled="false" useClasspath="true" />
</component>
</project>
@@ -0,0 +1,5 @@
<component name="CopyrightManager">
<settings default="">
<module2copyright />
</settings>
</component>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
</project>
@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavadocGenerationManager">
<option name="OUTPUT_DIRECTORY" />
<option name="OPTION_SCOPE" value="protected" />
<option name="OPTION_HIERARCHY" value="true" />
<option name="OPTION_NAVIGATOR" value="true" />
<option name="OPTION_INDEX" value="true" />
<option name="OPTION_SEPARATE_INDEX" value="true" />
<option name="OPTION_DOCUMENT_TAG_USE" value="false" />
<option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" />
<option name="OPTION_DOCUMENT_TAG_VERSION" value="false" />
<option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" />
<option name="OPTION_DEPRECATED_LIST" value="true" />
<option name="OTHER_OPTIONS" value="" />
<option name="HEAP_SIZE" />
<option name="LOCALE" />
<option name="OPEN_IN_BROWSER" value="true" />
</component>
<component name="ModuleEditorState">
<option name="LAST_EDITED_MODULE_NAME" />
<option name="LAST_EDITED_TAB_NAME" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_5" assert-keyword="true" jdk-15="true" project-jdk-name="IDEA jdk" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
<component name="masterDetails">
<states>
<state key="ArtifactsStructureConfigurable.UI">
<settings>
<artifact-editor />
<splitter-proportions />
</settings>
</state>
<state key="FacetStructureConfigurable.UI">
<settings>
<splitter-proportions />
</settings>
</state>
<state key="GlobalLibrariesConfigurable.UI">
<settings>
<splitter-proportions />
</settings>
</state>
<state key="ModuleStructureConfigurable.UI">
<settings>
<splitter-proportions />
</settings>
</state>
<state key="ProjectJDKs.UI">
<settings>
<last-edited>IDEA jdk</last-edited>
<splitter-proportions>
<option name="proportions">
<list>
<option value="0.2" />
</list>
</option>
</splitter-proportions>
</settings>
</state>
<state key="ProjectLibrariesConfigurable.UI">
<settings>
<splitter-proportions />
</settings>
</state>
</states>
</component>
</project>

Some files were not shown because too many files have changed in this diff Show More