mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote branch 'origin/master'
This commit is contained in:
@@ -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")
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+4
@@ -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);
|
||||
|
||||
+5
-3
@@ -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;
|
||||
|
||||
|
||||
+5
@@ -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) {
|
||||
|
||||
+2
-1
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-14
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
+16
@@ -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>
|
||||
|
||||
+8
-18
@@ -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();
|
||||
|
||||
+6
-5
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+27
-6
@@ -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
|
||||
|
||||
+6
-5
@@ -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()) {
|
||||
|
||||
+8
-7
@@ -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);
|
||||
|
||||
+1
-1
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
+10
-8
@@ -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
-1
@@ -1,7 +1,7 @@
|
||||
public class Test {
|
||||
{
|
||||
x = 2;
|
||||
<caret>
|
||||
foo();
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
public class Aaaaaaa {
|
||||
|
||||
{
|
||||
java.util.List<String> local = null;
|
||||
java.util.List<String> l = <caret>
|
||||
}
|
||||
|
||||
}
|
||||
+22
-6
@@ -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
|
||||
|
||||
+9
-2
@@ -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() {
|
||||
|
||||
-2
@@ -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);
|
||||
|
||||
@@ -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.
@@ -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>
|
||||
|
||||
|
||||
@@ -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
-2
@@ -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();
|
||||
}
|
||||
}
|
||||
+166
-100
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
+5
@@ -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
Reference in New Issue
Block a user