diff --git a/plugins/de.cognicrypt.core/src/de/cognicrypt/utils/Utils.java b/plugins/de.cognicrypt.core/src/de/cognicrypt/utils/Utils.java index 0e88ae6df..888ca3c63 100644 --- a/plugins/de.cognicrypt.core/src/de/cognicrypt/utils/Utils.java +++ b/plugins/de.cognicrypt.core/src/de/cognicrypt/utils/Utils.java @@ -1,302 +1,277 @@ -/******************************************************************************** - * Copyright (c) 2015-2019 TU Darmstadt, Paderborn University - * - * http://www.eclipse.org/legal/epl-2.0. SPDX-License-Identifier: EPL-2.0 - ********************************************************************************/ -package de.cognicrypt.utils; - -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.OptionalInt; -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Platform; -import org.eclipse.jdt.core.ICompilationUnit; -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IPackageFragment; -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jdt.internal.core.CompilationUnit; -import org.eclipse.jdt.core.search.IJavaSearchConstants; -import org.eclipse.jdt.core.search.IJavaSearchScope; -import org.eclipse.jdt.core.search.SearchEngine; -import org.eclipse.jdt.core.search.SearchParticipant; -import org.eclipse.jdt.core.search.SearchPattern; -import org.eclipse.jdt.core.search.SearchRequestor; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.ini4j.InvalidFileFormatException; -import org.ini4j.Wini; -import org.osgi.framework.Bundle; -import com.google.common.base.CharMatcher; -import de.cognicrypt.core.Activator; -import de.cognicrypt.core.Constants; - -public class Utils { - - static IWorkbenchWindow window = null; - - /** - * This method checks if a project passed as parameter is a Java project or not. - * - * @param Iproject - * @return true/false if project is Java project - */ - public static boolean checkIfJavaProjectSelected(final IProject project) { - try { - return project.hasNature(Constants.JavaNatureID); - } - catch (final CoreException e) { - Activator.getDefault().logError(e, Constants.NOT_HAVE_NATURE); - return false; - } - } - - public static List complileListOfJavaProjectsInWorkspace() { - final IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); - final List javaProjects = new ArrayList<>(); - if (projects.length > 0) { - for (int i = 0; i < projects.length; i++) { - if (Utils.checkIfJavaProjectSelected(projects[i])) { - javaProjects.add(projects[i]); - } - } - } - - return javaProjects; - } - - public static IResource findClassByName(final String className, final IProject currentProject) throws ClassNotFoundException { - try { - for (final IPackageFragment l : JavaCore.create(currentProject).getPackageFragments()) { - for (final ICompilationUnit cu : l.getCompilationUnits()) { - final IJavaElement cuResource = JavaCore.create(cu.getCorrespondingResource()); - for (IJavaElement a : (ArrayList)((CompilationUnit) cuResource).getChildrenOfType(7)) { - String name = cuResource.getParent().getElementName() + "." + a.getElementName(); - - if (name.startsWith(".")) { - name = name.substring(1); - } - if (name.equals(className)) { - return cu.getCorrespondingResource(); - } - } - } - } - } - catch (final JavaModelException e) { - throw new ClassNotFoundException("Class " + className + " not found.", e); - } - throw new ClassNotFoundException("Class " + className + " not found."); - } - - /** - * Overload for {@link UIUtils#getCurrentlyOpenFile(IEditorPart) getCurrentlyOpenFile(IEditor part)} - * - * @return Currently open file. - */ - public static IFile getCurrentlyOpenFile() { - return UIUtils.getCurrentlyOpenFile(UIUtils.getCurrentlyOpenEditor()); - } - - public static IProject getCurrentProject() { - final IFile currentlyOpenFile = Utils.getCurrentlyOpenFile(); - if (currentlyOpenFile != null) { - final IProject curProject = currentlyOpenFile.getProject(); - if (checkIfJavaProjectSelected(curProject)) { - return curProject; - } - } - final IProject selectedProject = Utils.getCurrentlySelectedIProject(); - if (selectedProject != null && checkIfJavaProjectSelected(selectedProject)) { - return selectedProject; - } - return null; - } - - /** - * This method searches the passed project for the class that contains the main method. - * - * @param project Project that is searched - * @param requestor Object that handles the search results - */ - public static void findMainMethodInCurrentProject(final IJavaProject project, final SearchRequestor requestor) { - final SearchPattern sp = SearchPattern.createPattern("main", IJavaSearchConstants.METHOD, IJavaSearchConstants.DECLARATIONS, SearchPattern.R_EXACT_MATCH); - - final SearchEngine se = new SearchEngine(); - final SearchParticipant[] searchParticipants = new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}; - final IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] {project}); - - try { - se.search(sp, searchParticipants, scope, requestor, null); - } - catch (final CoreException e) { - Activator.getDefault().logError(e, "Could not find main method in the project: "+project.getProject().getName()); - } - } - - /** - * This method searches the passed project for the class that contains the main method. - * - * @param project Project that is searched - * @param requestor Object that handles the search results - * @throws CoreException - */ - public static IFile findFileInProject(IContainer container, String name) { - try { - for (IResource res : container.members()) { - if (res instanceof IContainer) { - IFile file = findFileInProject((IContainer) res, name); - if (file != null) { - return file; - } - } else if (res instanceof IFile && (res.getName().equals(name.substring(name.lastIndexOf(".") + 1) + ".java"))) { - return (IFile) res; - } - } - } catch (CoreException e) { - Activator.getDefault().logError(e); - } - - return null; - } - - /** - * This method gets the project that is currently selected. - * - * @return Currently selected project. - */ - public static IProject getCurrentlySelectedIProject() { - ISelection curSel = getCurrentSelection(); - Object resource = null; - if ((resource = getIResourceFromSelection(curSel)) != null) { - return ((IProject) resource).getProject(); - } else { - return getJavaProjectFromSelection(curSel); - } - } - - private static ISelection getCurrentSelection() { - return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().getSelection(); - } - - public static IResource getCurrentlySelectedIResource() { - return getIResourceFromSelection(getCurrentSelection()); - } - - private static IResource getIResourceFromSelection(final ISelection selection) { - if (selection instanceof IStructuredSelection) { - final Object element = ((IStructuredSelection) selection).getFirstElement(); - if (element instanceof IResource) { - return (IResource) element; - } - } - return null; - } - - private static IProject getJavaProjectFromSelection(final ISelection selection) { - if (selection instanceof IStructuredSelection) { - final Object element = ((IStructuredSelection) selection).getFirstElement(); - if (element instanceof IJavaElement) { - return ((IJavaElement) element).getJavaProject().getProject(); - } - } - return null; - } - - public static File getResourceFromWithin(final String inputPath) { - return getResourceFromWithin(inputPath, Activator.PLUGIN_ID); - } - - /*** - * This method returns absolute path of a project-relative path. - * - * @param inputPath project-relative path - * @return absolute path - */ - public static File getResourceFromWithin(final String inputPath, final String pluginID) { - try { - final Bundle bundle = Platform.getBundle(pluginID); - if (bundle == null) { - return new File(inputPath); - } else { - final URL entry = bundle.getEntry(inputPath); - if (entry == null) { - return null; - } - final URL resolvedURL = FileLocator.toFileURL(entry); - URI resolvedURI = null; - if (!(resolvedURL == null)) { - resolvedURI = new URI(resolvedURL.getProtocol(), resolvedURL.getPath(), null); - } else { - resolvedURI = FileLocator.resolve(entry).toURI(); - } - return new File(resolvedURI); - } - } - catch (final IOException ex) { - Activator.getDefault().logError(ex, Constants.ERROR_MESSAGE_NO_FILE); - } catch (URISyntaxException ex) { - Activator.getDefault().logError(ex); - } - - return null; - } - - /*** - * Returns parsed objects of resources/configuration.ini file. - * @return Wini object - */ - public static Wini getConfig() { - Wini ini = null; - try { - ini = new Wini(getResourceFromWithin(Constants.CONFIG_FILE_PATH)); - } catch (InvalidFileFormatException e) { - Activator.getDefault().logError("Could not read the configuration file due to: " + e.getMessage()); - } catch (IOException e) { - Activator.getDefault().logError("Failed identifying configuration file due to: " + e.getMessage()); - } - return ini; - } - - public static String filterQuotes(final String dirty) { - return CharMatcher.anyOf("\"").removeFrom(dirty); - } - - public static int getFirstIndexofUCL(final String searchString) { - final OptionalInt index = searchString.chars().filter(n -> Character.isUpperCase(n)).findFirst(); - if (index.isPresent()) { - return searchString.indexOf(index.getAsInt()); - } else { - return -1; - } - } - - public static boolean isSubType(String typeOne, String typeTwo) { - boolean subTypes = typeOne.equals(typeTwo); - subTypes |= ("byte".equals(typeOne) && (typeOne + "[]").equals(typeTwo)); - if (!subTypes) { - try { - subTypes = Class.forName(typeOne).isAssignableFrom(Class.forName(typeTwo)); - } - catch (ClassNotFoundException e) { - Activator.getDefault().logError(e); - } - } - return subTypes; - } -} +/******************************************************************************** + * Copyright (c) 2015-2019 TU Darmstadt, Paderborn University + * + * http://www.eclipse.org/legal/epl-2.0. SPDX-License-Identifier: EPL-2.0 + ********************************************************************************/ +package de.cognicrypt.utils; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.OptionalInt; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.internal.core.CompilationUnit; +import org.eclipse.jdt.core.search.IJavaSearchConstants; +import org.eclipse.jdt.core.search.IJavaSearchScope; +import org.eclipse.jdt.core.search.SearchEngine; +import org.eclipse.jdt.core.search.SearchParticipant; +import org.eclipse.jdt.core.search.SearchPattern; +import org.eclipse.jdt.core.search.SearchRequestor; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.ini4j.InvalidFileFormatException; +import org.ini4j.Wini; +import org.osgi.framework.Bundle; +import com.google.common.base.CharMatcher; +import de.cognicrypt.core.Activator; +import de.cognicrypt.core.Constants; + +public class Utils { + + static IWorkbenchWindow window = null; + + /** + * This method checks if a project passed as parameter is a Java project or not. + * + * @param Iproject + * @return true/false if project is Java project + */ + public static boolean checkIfJavaProjectSelected(final IProject project) { + try { + return project.hasNature(Constants.JavaNatureID); + } + catch (final CoreException e) { + Activator.getDefault().logError(e, Constants.NOT_HAVE_NATURE); + return false; + } + } + + public static List complileListOfJavaProjectsInWorkspace() { + final IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); + final List javaProjects = new ArrayList<>(); + if (projects.length > 0) { + for (int i = 0; i < projects.length; i++) { + if (Utils.checkIfJavaProjectSelected(projects[i])) { + javaProjects.add(projects[i]); + } + } + } + + return javaProjects; + } + + /** + * Overload for {@link UIUtils#getCurrentlyOpenFile(IEditorPart) getCurrentlyOpenFile(IEditor part)} + * + * @return Currently open file. + */ + public static IFile getCurrentlyOpenFile() { + return UIUtils.getCurrentlyOpenFile(UIUtils.getCurrentlyOpenEditor()); + } + + public static IProject getCurrentProject() { + final IFile currentlyOpenFile = Utils.getCurrentlyOpenFile(); + if (currentlyOpenFile != null) { + final IProject curProject = currentlyOpenFile.getProject(); + if (checkIfJavaProjectSelected(curProject)) { + return curProject; + } + } + final IProject selectedProject = Utils.getCurrentlySelectedIProject(); + if (selectedProject != null && checkIfJavaProjectSelected(selectedProject)) { + return selectedProject; + } + return null; + } + + /** + * This method searches the passed project for the class that contains the main method. + * + * @param project Project that is searched + * @param requestor Object that handles the search results + */ + public static void findMainMethodInCurrentProject(final IJavaProject project, final SearchRequestor requestor) { + final SearchPattern sp = SearchPattern.createPattern("main", IJavaSearchConstants.METHOD, IJavaSearchConstants.DECLARATIONS, SearchPattern.R_EXACT_MATCH); + + final SearchEngine se = new SearchEngine(); + final SearchParticipant[] searchParticipants = new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}; + final IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] {project}); + + try { + se.search(sp, searchParticipants, scope, requestor, null); + } + catch (final CoreException e) { + Activator.getDefault().logError(e, "Could not find main method in the project: "+project.getProject().getName()); + } + } + + /** + * This method searches the passed project for the class that contains the main method. + * + * @param project Project that is searched + * @param requestor Object that handles the search results + * @throws CoreException + */ + public static IFile findFileInProject(IContainer container, String name) { + try { + for (IResource res : container.members()) { + if (res instanceof IContainer) { + IFile file = findFileInProject((IContainer) res, name); + if (file != null) { + return file; + } + } else if (res instanceof IFile && (res.getName().equals(name.substring(name.lastIndexOf(".") + 1) + ".java"))) { + return (IFile) res; + } + } + } catch (CoreException e) { + Activator.getDefault().logError(e); + } + + return null; + } + + /** + * This method gets the project that is currently selected. + * + * @return Currently selected project. + */ + public static IProject getCurrentlySelectedIProject() { + ISelection curSel = getCurrentSelection(); + Object resource = null; + if ((resource = getIResourceFromSelection(curSel)) != null) { + return ((IProject) resource).getProject(); + } else { + return getJavaProjectFromSelection(curSel); + } + } + + private static ISelection getCurrentSelection() { + return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().getSelection(); + } + + public static IResource getCurrentlySelectedIResource() { + return getIResourceFromSelection(getCurrentSelection()); + } + + private static IResource getIResourceFromSelection(final ISelection selection) { + if (selection instanceof IStructuredSelection) { + final Object element = ((IStructuredSelection) selection).getFirstElement(); + if (element instanceof IResource) { + return (IResource) element; + } + } + return null; + } + + private static IProject getJavaProjectFromSelection(final ISelection selection) { + if (selection instanceof IStructuredSelection) { + final Object element = ((IStructuredSelection) selection).getFirstElement(); + if (element instanceof IJavaElement) { + return ((IJavaElement) element).getJavaProject().getProject(); + } + } + return null; + } + + public static File getResourceFromWithin(final String inputPath) { + return getResourceFromWithin(inputPath, Activator.PLUGIN_ID); + } + + /*** + * This method returns absolute path of a project-relative path. + * + * @param inputPath project-relative path + * @return absolute path + */ + public static File getResourceFromWithin(final String inputPath, final String pluginID) { + try { + final Bundle bundle = Platform.getBundle(pluginID); + if (bundle == null) { + return new File(inputPath); + } else { + final URL entry = bundle.getEntry(inputPath); + if (entry == null) { + return null; + } + final URL resolvedURL = FileLocator.toFileURL(entry); + URI resolvedURI = null; + if (!(resolvedURL == null)) { + resolvedURI = new URI(resolvedURL.getProtocol(), resolvedURL.getPath(), null); + } else { + resolvedURI = FileLocator.resolve(entry).toURI(); + } + return new File(resolvedURI); + } + } + catch (final IOException ex) { + Activator.getDefault().logError(ex, Constants.ERROR_MESSAGE_NO_FILE); + } catch (URISyntaxException ex) { + Activator.getDefault().logError(ex); + } + + return null; + } + + /*** + * Returns parsed objects of resources/configuration.ini file. + * @return Wini object + */ + public static Wini getConfig() { + Wini ini = null; + try { + ini = new Wini(getResourceFromWithin(Constants.CONFIG_FILE_PATH)); + } catch (InvalidFileFormatException e) { + Activator.getDefault().logError("Could not read the configuration file due to: " + e.getMessage()); + } catch (IOException e) { + Activator.getDefault().logError("Failed identifying configuration file due to: " + e.getMessage()); + } + return ini; + } + + public static String filterQuotes(final String dirty) { + return CharMatcher.anyOf("\"").removeFrom(dirty); + } + + public static int getFirstIndexofUCL(final String searchString) { + final OptionalInt index = searchString.chars().filter(n -> Character.isUpperCase(n)).findFirst(); + if (index.isPresent()) { + return searchString.indexOf(index.getAsInt()); + } else { + return -1; + } + } + + public static boolean isSubType(String typeOne, String typeTwo) { + boolean subTypes = typeOne.equals(typeTwo); + subTypes |= ("byte".equals(typeOne) && (typeOne + "[]").equals(typeTwo)); + if (!subTypes) { + try { + subTypes = Class.forName(typeOne).isAssignableFrom(Class.forName(typeTwo)); + } + catch (ClassNotFoundException e) { + Activator.getDefault().logError(e); + } + } + return subTypes; + } +} \ No newline at end of file diff --git a/plugins/de.cognicrypt.staticanalyzer.kotlin/.classpath b/plugins/de.cognicrypt.staticanalyzer.kotlin/.classpath new file mode 100644 index 000000000..43507644f --- /dev/null +++ b/plugins/de.cognicrypt.staticanalyzer.kotlin/.classpath @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/plugins/de.cognicrypt.staticanalyzer.kotlin/.project b/plugins/de.cognicrypt.staticanalyzer.kotlin/.project new file mode 100644 index 000000000..5be34d521 --- /dev/null +++ b/plugins/de.cognicrypt.staticanalyzer.kotlin/.project @@ -0,0 +1,34 @@ + + + de.cognicrypt.staticanalyzer.kotlin + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/plugins/de.cognicrypt.staticanalyzer.kotlin/.settings/org.eclipse.core.resources.prefs b/plugins/de.cognicrypt.staticanalyzer.kotlin/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 000000000..99f26c020 --- /dev/null +++ b/plugins/de.cognicrypt.staticanalyzer.kotlin/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/plugins/de.cognicrypt.staticanalyzer.kotlin/.settings/org.eclipse.jdt.core.prefs b/plugins/de.cognicrypt.staticanalyzer.kotlin/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..4e4a3ada9 --- /dev/null +++ b/plugins/de.cognicrypt.staticanalyzer.kotlin/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/plugins/de.cognicrypt.staticanalyzer.kotlin/.settings/org.eclipse.m2e.core.prefs b/plugins/de.cognicrypt.staticanalyzer.kotlin/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 000000000..f897a7f1c --- /dev/null +++ b/plugins/de.cognicrypt.staticanalyzer.kotlin/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/plugins/de.cognicrypt.staticanalyzer.kotlin/META-INF/MANIFEST.MF b/plugins/de.cognicrypt.staticanalyzer.kotlin/META-INF/MANIFEST.MF new file mode 100644 index 000000000..6fc276382 --- /dev/null +++ b/plugins/de.cognicrypt.staticanalyzer.kotlin/META-INF/MANIFEST.MF @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: CogniCrypt Static Analyzer for Kotlin +Bundle-SymbolicName: de.cognicrypt.staticanalyzer.kotlin;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: de.cognicrypt.staticanalyzer.kotlin.Activator +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Automatic-Module-Name: de.cognicrypt.staticanalyzer.kotlin +Bundle-ClassPath: ., + lib/ +Require-Bundle: org.eclipse.jdt.core, + org.eclipse.m2e.maven.runtime, + org.eclipse.core.runtime, + org.eclipse.core.resources, + org.eclipse.ui, + org.jetbrains.kotlin.core;bundle-version="0.8.19";resolution:=optional, + de.cognicrypt.staticanalyzer;bundle-version="1.0.0" diff --git a/plugins/de.cognicrypt.staticanalyzer.kotlin/build.properties b/plugins/de.cognicrypt.staticanalyzer.kotlin/build.properties new file mode 100644 index 000000000..a5d59a96d --- /dev/null +++ b/plugins/de.cognicrypt.staticanalyzer.kotlin/build.properties @@ -0,0 +1,7 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + src/,\ + lib/ +source.. = src/ diff --git a/plugins/de.cognicrypt.staticanalyzer.kotlin/lib/org.jetbrains.kotlin.core.jar b/plugins/de.cognicrypt.staticanalyzer.kotlin/lib/org.jetbrains.kotlin.core.jar new file mode 100644 index 000000000..ebb37563c Binary files /dev/null and b/plugins/de.cognicrypt.staticanalyzer.kotlin/lib/org.jetbrains.kotlin.core.jar differ diff --git a/plugins/de.cognicrypt.staticanalyzer.kotlin/plugin.xml b/plugins/de.cognicrypt.staticanalyzer.kotlin/plugin.xml new file mode 100644 index 000000000..ab1e9d01a --- /dev/null +++ b/plugins/de.cognicrypt.staticanalyzer.kotlin/plugin.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/plugins/de.cognicrypt.staticanalyzer.kotlin/pom.xml b/plugins/de.cognicrypt.staticanalyzer.kotlin/pom.xml new file mode 100644 index 000000000..3b2054c2c --- /dev/null +++ b/plugins/de.cognicrypt.staticanalyzer.kotlin/pom.xml @@ -0,0 +1,152 @@ + + 4.0.0 + de.cognicrypt + de.cognicrypt.staticanalyzer.kotlin + eclipse-plugin + + de.cognicrypt + de.cognicrypt.parent + 1.0.0-SNAPSHOT + ../../pom.xml + + + + + org.eclipse.tycho + tycho-maven-plugin + ${tycho-version} + true + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.17 + + ../../shippable/testresults + + + + org.apache.maven.surefire + surefire-junit4 + 2.17 + + + junit + junit + 4.12 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + + junit + junit + 4.12 + + + + + compiletests + test-compile + + testCompile + + + 1.8 + 1.8 + + + + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.eclipse.tycho + + tycho-packaging-plugin + + + [0.26.0,) + + + build-qualifier + validate-id + validate-version + + + + + + + + + org.eclipse.tycho + + tycho-compiler-plugin + + + [0.26.0,) + + + compile + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + [0.26.0,) + + + test-compile + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + [0.26.0,) + + + test + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/de.cognicrypt.staticanalyzer.kotlin/src/de/cognicrypt/staticanalyzer/kotlin/Activator.java b/plugins/de.cognicrypt.staticanalyzer.kotlin/src/de/cognicrypt/staticanalyzer/kotlin/Activator.java new file mode 100644 index 000000000..74ef2bbce --- /dev/null +++ b/plugins/de.cognicrypt.staticanalyzer.kotlin/src/de/cognicrypt/staticanalyzer/kotlin/Activator.java @@ -0,0 +1,65 @@ +package de.cognicrypt.staticanalyzer.kotlin; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "de.cognicrypt.staticanalyzer.kotlin"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + + private void log(final int severity, final String message, final Exception ex) { + getLog().log(new Status(severity, Activator.PLUGIN_ID, message, ex)); + } + + public void logError(final Exception ex) { + logError(ex, ex.getMessage()); + } + + public void logError(final Exception ex, final String message) { + log(IStatus.ERROR, message, ex); + } + + public void logError(final String message) { + log(IStatus.ERROR, message, null); + } + + public void logInfo(final String message) { + log(IStatus.INFO, message, null); + } +} diff --git a/plugins/de.cognicrypt.staticanalyzer.kotlin/src/de/cognicrypt/staticanalyzer/kotlin/KotlinListener.java b/plugins/de.cognicrypt.staticanalyzer.kotlin/src/de/cognicrypt/staticanalyzer/kotlin/KotlinListener.java new file mode 100644 index 000000000..f98c000fb --- /dev/null +++ b/plugins/de.cognicrypt.staticanalyzer.kotlin/src/de/cognicrypt/staticanalyzer/kotlin/KotlinListener.java @@ -0,0 +1,21 @@ +package de.cognicrypt.staticanalyzer.kotlin; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.jdt.core.JavaModelException; + +import de.cognicrypt.staticanalyzer.IListener; +import de.cognicrypt.staticanalyzer.kotlin.utilities.KotlinUtils; + +public class KotlinListener implements IListener { + + @Override + public void listen1(IProject ip) { + KotlinUtils.compileKotlinFiles(ip); + } + + @Override + public IResource listen2(String name, IProject ip) throws JavaModelException, ClassNotFoundException { + return KotlinUtils.findKotlinClassByName(name, ip); + } +} diff --git a/plugins/de.cognicrypt.staticanalyzer.kotlin/src/de/cognicrypt/staticanalyzer/kotlin/utilities/KotlinUtils.java b/plugins/de.cognicrypt.staticanalyzer.kotlin/src/de/cognicrypt/staticanalyzer/kotlin/utilities/KotlinUtils.java new file mode 100644 index 000000000..7ae082f40 --- /dev/null +++ b/plugins/de.cognicrypt.staticanalyzer.kotlin/src/de/cognicrypt/staticanalyzer/kotlin/utilities/KotlinUtils.java @@ -0,0 +1,247 @@ +package de.cognicrypt.staticanalyzer.kotlin.utilities; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Model; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.apache.maven.model.io.xpp3.MavenXpp3Writer; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.jetbrains.kotlin.core.compiler.KotlinCompiler; +import org.jetbrains.kotlin.core.model.KotlinNature; + +public class KotlinUtils { + + private static final String KOTLIN_FILE_EXTENSION = ".kt"; + + public static void compileKotlinFiles(IProject ip) { + IJavaProject javaProject = JavaCore.create(ip); + + if(Platform.getBundle("org.jetbrains.kotlin.core") != null) { + if(KotlinNature.hasKotlinNature(ip)) { + try { + if(ip.hasNature("org.eclipse.m2e.core.maven2Nature")) { + if(KotlinUtils.verifyKotlinDependency(javaProject)) { + + final Job builder = new Job("Custom Builder") { + + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + ip.build(IncrementalProjectBuilder.CLEAN_BUILD, null); + } catch (CoreException e) { + de.cognicrypt.staticanalyzer.Activator.getDefault().logError(e); + } + return Status.OK_STATUS; + } + }; + builder.setPriority(Job.LONG); + builder.schedule(); + + while(builder.getState() != Job.NONE) { + Thread.sleep(3); + } + + KotlinUtils.waitForBuildAndRefreshJobs(); + + if(KotlinCompiler.compileKotlinFiles(javaProject).compiledCorrectly()) { + de.cognicrypt.staticanalyzer.Activator.getDefault().logInfo("Finished compiling kotlin files."); + } else { + de.cognicrypt.staticanalyzer.Activator.getDefault().logInfo("Cannot compile some kotlin files due to errors. Static analysis skipped them."); + } + } + else { + de.cognicrypt.staticanalyzer.Activator.getDefault().logInfo("Cannot compile kotlin files without kotlin-stdlib dependency."); + de.cognicrypt.staticanalyzer.Activator.getDefault().logInfo("Static analysis skipped all kotlin files."); + } + } + else { + if(KotlinCompiler.compileKotlinFiles(javaProject).compiledCorrectly()) { + de.cognicrypt.staticanalyzer.Activator.getDefault().logInfo("Finished compiling kotlin files."); + } else { + de.cognicrypt.staticanalyzer.Activator.getDefault().logInfo("Cannot compile some kotlin files due to errors. Static analysis skipped them."); + } + } + } catch (CoreException | OperationCanceledException | InterruptedException e) { + de.cognicrypt.staticanalyzer.Activator.getDefault().logError(e); + } + } + } + } + + public static IResource findKotlinClassByName(final String className, final IProject currentProject) + throws JavaModelException, ClassNotFoundException { + if(Platform.getBundle("org.jetbrains.kotlin.core") != null) { + // This part is required because Eclipse JDT doesn’t provide any mapping of kotlin light classes to its source code + // As a result the above IPackageFragment.getCompilationUnits() doesn't return any kotlin .class files + if(KotlinNature.hasKotlinNature(currentProject)) { + + // computing corresponding source filename, since in kotlin .class filename is changed + // Eg. Demo.kt is compiled to DemoKt.class + String[] temp = className.split("\\."); + String classFileName = temp[temp.length-1]; + String srcFilename = ""; + + if(classFileName.substring(classFileName.length()-2).equals("Kt")) { + srcFilename = classFileName.substring(0, classFileName.length()-2) + KOTLIN_FILE_EXTENSION; + } + else if(classFileName.contains("$")) { + srcFilename = Arrays.asList(classFileName.split("\\$")).get(0) + KOTLIN_FILE_EXTENSION; + } + // because in some projects the class names aren't renamed + else { + srcFilename = classFileName + KOTLIN_FILE_EXTENSION; + } + + for (final IPackageFragment l : JavaCore.create(currentProject).getPackageFragments()) { + // this check is needed because IJavaProject.getPackageFragments() returns dependencies as well + if(l.getKind() == IPackageFragmentRoot.K_SOURCE) { + // removing the from path returned by IPackageFragment.getPath() because IProject.getFile() also appends it + String[] originalPath = l.getPath().toString().split(File.separator); + String[] modifiedPath = Arrays.copyOfRange(originalPath, 2, originalPath.length); + String packageName = String.join(File.separator, modifiedPath); + + IFile sourceFile = currentProject.getFile(packageName + File.separator + srcFilename); + if(sourceFile.exists()) { + return (IResource) sourceFile; + } + } + } + } + } + + throw new ClassNotFoundException("Class " + className + " not found."); + } + + public static boolean verifyKotlinDependency(IJavaProject javaProject) { + IProject project = javaProject.getProject(); + IFile pomFile = project.getFile("pom.xml"); + boolean isPresent = false; + try { + MavenProject mavenProject = loadProject(pomFile.getLocation().toFile()); + List dependencies = mavenProject.getDependencies(); + + for (Dependency dependency : dependencies) { + if("kotlin-stdlib".equals(dependency.getArtifactId())) { + isPresent = true; + } + } + if(!isPresent) { + if(requestUsersPermission() == SWT.YES) { + addKotlinDependency(mavenProject, dependencies); + isPresent = true; + } + } + } catch (Exception e) { + de.cognicrypt.staticanalyzer.Activator.getDefault().logError(e); + } + return isPresent; + } + + public static void waitForBuildAndRefreshJobs() { + ArrayList jobs = new ArrayList(); + while(true) + { + jobs.clear(); + jobs.addAll(Arrays.asList(Job.getJobManager().find(ResourcesPlugin.FAMILY_AUTO_BUILD))); + jobs.addAll(Arrays.asList(Job.getJobManager().find(ResourcesPlugin.FAMILY_AUTO_REFRESH))); + jobs.addAll(Arrays.asList(Job.getJobManager().find(ResourcesPlugin.FAMILY_MANUAL_BUILD))); + jobs.addAll(Arrays.asList(Job.getJobManager().find(ResourcesPlugin.FAMILY_MANUAL_REFRESH))); + if(jobs.isEmpty()) { + return; + } + + boolean buildSuccess; + do { + buildSuccess = true; + for (Job job : jobs) { + if(job.getState() != Job.NONE) + buildSuccess = false; + } + } + while(!buildSuccess); + } + } + + private static void addKotlinDependency(MavenProject project, List dependencies) { + Dependency kotlinDependency = new Dependency(); + kotlinDependency.setGroupId("org.jetbrains.kotlin"); + kotlinDependency.setArtifactId("kotlin-stdlib"); + kotlinDependency.setVersion("1.3.61"); + kotlinDependency.setType("jar"); + dependencies.add(kotlinDependency); + project.setDependencies(dependencies); + storeProject(project); + } + + private static void storeProject(MavenProject project) { + MavenXpp3Writer mavenWriter = new MavenXpp3Writer(); + Model model = project.getModel(); + try { + FileWriter writer = new FileWriter(model.getPomFile()); + mavenWriter.write(writer, model); + de.cognicrypt.staticanalyzer.Activator.getDefault().logInfo("Required kotlin dependency added to pom."); + } catch (IOException e) { + de.cognicrypt.staticanalyzer.Activator.getDefault().logError(e); + } + } + + private static MavenProject loadProject(File pomFile) throws IOException, XmlPullParserException + { + MavenProject ret = null; + MavenXpp3Reader mavenReader = new MavenXpp3Reader(); + + if (pomFile != null && pomFile.exists()) + { + try (FileReader reader = new FileReader(pomFile)) { + Model model = mavenReader.read(reader); + model.setPomFile(pomFile); + ret = new MavenProject(model); + } + } + return ret; + } + + private static int requestUsersPermission() { + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + MessageBox dialog = new MessageBox(window.getShell(), + SWT.APPLICATION_MODAL | SWT.ICON_QUESTION | SWT.YES | SWT.NO); + return selectedDialogOption(dialog); + } + + private static int selectedDialogOption(MessageBox dialog) { + dialog.setMessage("Analysis requires maven kotlin-stdlib dependency. Would you like to add it?"); + dialog.setText("CAUTION"); + return dialog.open(); + } + + +} diff --git a/plugins/de.cognicrypt.staticanalyzer/.classpath b/plugins/de.cognicrypt.staticanalyzer/.classpath index 66438e56a..a579985ce 100644 --- a/plugins/de.cognicrypt.staticanalyzer/.classpath +++ b/plugins/de.cognicrypt.staticanalyzer/.classpath @@ -1,8 +1,8 @@ - - - - - - - - + + + + + + + + diff --git a/plugins/de.cognicrypt.staticanalyzer/META-INF/MANIFEST.MF b/plugins/de.cognicrypt.staticanalyzer/META-INF/MANIFEST.MF index b547db499..951b7432c 100644 --- a/plugins/de.cognicrypt.staticanalyzer/META-INF/MANIFEST.MF +++ b/plugins/de.cognicrypt.staticanalyzer/META-INF/MANIFEST.MF @@ -24,3 +24,4 @@ Bundle-ClassPath: ., resources/ Automatic-Module-Name: de.cognicrypt.staticanalyzer Import-Package: org.eclipse.ui.texteditor +Export-Package: de.cognicrypt.staticanalyzer diff --git a/plugins/de.cognicrypt.staticanalyzer/plugin.xml b/plugins/de.cognicrypt.staticanalyzer/plugin.xml index 8cee4d356..e7e278735 100644 --- a/plugins/de.cognicrypt.staticanalyzer/plugin.xml +++ b/plugins/de.cognicrypt.staticanalyzer/plugin.xml @@ -1,6 +1,7 @@ + diff --git a/plugins/de.cognicrypt.staticanalyzer/schema/listeners.exsd b/plugins/de.cognicrypt.staticanalyzer/schema/listeners.exsd new file mode 100644 index 000000000..848bdaedc --- /dev/null +++ b/plugins/de.cognicrypt.staticanalyzer/schema/listeners.exsd @@ -0,0 +1,99 @@ + + + + + + + + + [Enter description of this extension point.] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Enter the first release in which this extension point appears.] + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + [Enter API information here.] + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + diff --git a/plugins/de.cognicrypt.staticanalyzer/src/de/cognicrypt/staticanalyzer/IListener.java b/plugins/de.cognicrypt.staticanalyzer/src/de/cognicrypt/staticanalyzer/IListener.java new file mode 100644 index 000000000..9cfeaee52 --- /dev/null +++ b/plugins/de.cognicrypt.staticanalyzer/src/de/cognicrypt/staticanalyzer/IListener.java @@ -0,0 +1,10 @@ +package de.cognicrypt.staticanalyzer; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.jdt.core.JavaModelException; + +public interface IListener { + void listen1(IProject ip); + IResource listen2(String name, IProject ip) throws JavaModelException, ClassNotFoundException; +} diff --git a/plugins/de.cognicrypt.staticanalyzer/src/de/cognicrypt/staticanalyzer/handlers/AnalysisKickOff.java b/plugins/de.cognicrypt.staticanalyzer/src/de/cognicrypt/staticanalyzer/handlers/AnalysisKickOff.java index 168a7d4d8..522dfac6a 100644 --- a/plugins/de.cognicrypt.staticanalyzer/src/de/cognicrypt/staticanalyzer/handlers/AnalysisKickOff.java +++ b/plugins/de.cognicrypt.staticanalyzer/src/de/cognicrypt/staticanalyzer/handlers/AnalysisKickOff.java @@ -6,16 +6,20 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; + import de.cognicrypt.core.Constants; import de.cognicrypt.staticanalyzer.Activator; +import de.cognicrypt.staticanalyzer.IListener; import de.cognicrypt.staticanalyzer.results.ErrorMarkerGenerator; import de.cognicrypt.staticanalyzer.results.ResultsCCUIListener; import de.cognicrypt.utils.Utils; @@ -30,6 +34,7 @@ public class AnalysisKickOff { private static ResultsCCUIListener resultsReporter; private IJavaProject curProj; private boolean depOnly = false; + private IProject ip; public void analyzeDependenciesOnly(final Boolean depOnly) { this.depOnly = depOnly; @@ -47,7 +52,6 @@ public void analyzeDependenciesOnly(final Boolean depOnly) { */ public boolean setUp(final IJavaElement iJavaElement) { - IProject ip = null; if (iJavaElement == null) { ip = Utils.getCurrentProject(); } else { @@ -86,9 +90,45 @@ public boolean setUp(final IJavaElement iJavaElement) { Activator.getDefault().logInfo("JavaCore could not create IJavaProject for project " + ip.getName() + "."); return false; } - this.curProj = javaProject; - return true; - } + + IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor("de.cognicrypt.staticanalyzer.listeners"); + try { + for (IConfigurationElement e : config) { + final Object o = + e.createExecutableExtension("class"); + if (o instanceof IListener) { +// executeExtension(o); + ((IListener) o).listen1(ip); + } + } + } catch (CoreException ex) { + Activator.getDefault().logError(ex); + } + + this.curProj = javaProject; + return true; + } + + /* + * The code below uses the ISafeRunnable interface. This interface protects + * the plug-in which defines the extension point from malfunction extensions. + * If an extension throws an Exception, it will be caught by ISafeRunnable and + * the remaining extensions will still get executed. + */ +// private void executeExtension(final Object o) { +// ISafeRunnable runnable = new ISafeRunnable() { +// @Override +// public void handleException(Throwable e) { +// Activator.getDefault().logError("Exception in kotlin plugin"); +// } +// +// @Override +// public void run() throws Exception { +// ((IListener) o).listen1(ip); +// } +// }; +// SafeRunner.run(runnable); +// } /** * This method executes the actual analysis. diff --git a/plugins/de.cognicrypt.staticanalyzer/src/de/cognicrypt/staticanalyzer/results/ResultsCCUIListener.java b/plugins/de.cognicrypt.staticanalyzer/src/de/cognicrypt/staticanalyzer/results/ResultsCCUIListener.java index 397ea2316..6ff9501cf 100644 --- a/plugins/de.cognicrypt.staticanalyzer/src/de/cognicrypt/staticanalyzer/results/ResultsCCUIListener.java +++ b/plugins/de.cognicrypt.staticanalyzer/src/de/cognicrypt/staticanalyzer/results/ResultsCCUIListener.java @@ -16,17 +16,16 @@ import java.util.Map.Entry; import java.util.Optional; import java.util.Set; + import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; -import org.eclipse.jdt.core.ICompilationUnit; -import org.eclipse.jdt.core.IPackageDeclaration; -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jface.preference.IPreferenceStore; import org.w3c.dom.Node; + import com.google.common.collect.Multimap; import com.google.common.collect.Table; + import boomerang.BackwardQuery; import boomerang.Query; import boomerang.jimple.Statement; @@ -52,11 +51,11 @@ import de.cognicrypt.core.Constants; import de.cognicrypt.core.Constants.Severities; import de.cognicrypt.staticanalyzer.Activator; +import de.cognicrypt.staticanalyzer.utilities.Utils; import de.cognicrypt.staticanalyzer.view.AnalysisData; import de.cognicrypt.staticanalyzer.view.ResultsUnit; import de.cognicrypt.staticanalyzer.view.StatisticsView; import de.cognicrypt.staticanalyzer.view.Stats; -import de.cognicrypt.utils.Utils; import de.cognicrypt.utils.XMLParser; import soot.SootClass; import soot.Value; @@ -132,16 +131,8 @@ public void reportError(final AbstractError error) { final int stmtId = error.hashCode(); HashMap errorInfoMap = new HashMap<>(); - ICompilationUnit javaFile = (ICompilationUnit) JavaCore.create(sourceFile); - String className = ""; - try { - for (IPackageDeclaration decl : javaFile.getPackageDeclarations()) { - className += decl.getElementName() + "."; - } - } - catch (JavaModelException e1) {} - className += javaFile.getElementName().substring(0, javaFile.getElementName().lastIndexOf(".")); - + String className = sourceFile.getName(); + if (stat.getClassesAnalysed().containsKey(className)) { AnalysisData data = stat.getClassesAnalysed().get(className); data.addError(error); diff --git a/plugins/de.cognicrypt.staticanalyzer/src/de/cognicrypt/staticanalyzer/utilities/Utils.java b/plugins/de.cognicrypt.staticanalyzer/src/de/cognicrypt/staticanalyzer/utilities/Utils.java new file mode 100644 index 000000000..950f9d5ba --- /dev/null +++ b/plugins/de.cognicrypt.staticanalyzer/src/de/cognicrypt/staticanalyzer/utilities/Utils.java @@ -0,0 +1,53 @@ +package de.cognicrypt.staticanalyzer.utilities; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; + +import de.cognicrypt.staticanalyzer.Activator; +import de.cognicrypt.staticanalyzer.IListener; + +public class Utils { + + public static IResource findClassByName(final String className, final IProject currentProject) throws ClassNotFoundException { + try { + for (final IPackageFragment l : JavaCore.create(currentProject).getPackageFragments()) { + for (final ICompilationUnit cu : l.getCompilationUnits()) { + final IJavaElement cuResource = JavaCore.create(cu.getCorrespondingResource()); + String name = cuResource.getParent().getElementName() + "." + cuResource.getElementName(); + + if (name.startsWith(".")) { + name = name.substring(1); + } + if (name.startsWith(className)) { + return cu.getCorrespondingResource(); + } + } + } + + IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor("de.cognicrypt.staticanalyzer.listeners"); + try { + for (IConfigurationElement e : config) { + final Object o = + e.createExecutableExtension("class"); + if (o instanceof IListener) { + return ((IListener) o).listen2(className, currentProject); + } + } + } catch (CoreException ex) { + Activator.getDefault().logError(ex); + } + } + catch (final JavaModelException e) { + throw new ClassNotFoundException("Class " + className + " not found.", e); + } + throw new ClassNotFoundException("Class " + className + " not found."); + } +} diff --git a/pom.xml b/pom.xml index bcf0a5b92..13c614e8b 100644 --- a/pom.xml +++ b/pom.xml @@ -39,6 +39,11 @@ soot release https://soot-build.cs.uni-paderborn.de/nexus/repository/soot-release/ + + kotlin + p2 + https://dl.bintray.com/jetbrains/kotlin/eclipse-plugin/last/ + @@ -93,6 +98,7 @@ plugins/de.cognicrypt.codegenerator/ plugins/de.cognicrypt.codegenerator.tests/ plugins/de.cognicrypt.staticanalyzer/ + plugins/de.cognicrypt.staticanalyzer.kotlin/ plugins/de.cognicrypt.integrator.task/ plugins/de.cognicrypt.integrator.primitive/ features/de.cognicrypt.core.feature/