...
 
Commits (12)
de.loskutov.BytecodeOutline/debug=false
org.eclipse.jdt.bcoview/debug=false
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>de.loskutov.ByteCodeOutline</name>
<name>org.eclipse.jdt.bcoview</name>
<comment></comment>
<projects>
</projects>
......
......@@ -12,8 +12,11 @@ org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
......@@ -24,6 +27,7 @@ org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
org.eclipse.jdt.core.compiler.problem.APILeak=warning
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=warning
......@@ -54,7 +58,7 @@ org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
org.eclipse.jdt.core.compiler.problem.missingDefaultCase=warning
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
......@@ -74,19 +78,21 @@ org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
org.eclipse.jdt.core.compiler.problem.nullReference=warning
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=warning
......@@ -96,19 +102,25 @@ org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=ignore
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName=warning
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
......@@ -121,6 +133,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled
org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,HIGH
......
This diff is collapsed.
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Bytecode Outline
Bundle-SymbolicName: de.loskutov.BytecodeOutline;singleton:=true
Bundle-Version: 2.6.0.qualifier
Bundle-SymbolicName: org.eclipse.jdt.bcoview;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-ClassPath: .
Bundle-Activator: de.loskutov.bco.BytecodeOutlinePlugin
Bundle-Activator: org.eclipse.jdt.bcoview.BytecodeOutlinePlugin
Bundle-Vendor: Andrey Loskutov
Require-Bundle: org.eclipse.ui,
org.eclipse.ui.editors,
......@@ -20,11 +20,13 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.debug.ui,
org.eclipse.jdt.debug,
org.junit;resolution:=optional,
org.objectweb.asm;bundle-version="6.2.1",
org.objectweb.asm.tree;bundle-version="6.2.1",
org.objectweb.asm.analysis;bundle-version="6.2.1",
org.objectweb.asm.commons;bundle-version="6.2.1",
org.objectweb.asm.util;bundle-version="6.2.1"
org.objectweb.asm;bundle-version="7.0.0",
org.objectweb.asm.tree;bundle-version="7.0.0",
org.objectweb.asm.analysis;bundle-version="7.0.0",
org.objectweb.asm.commons;bundle-version="7.0.0",
org.objectweb.asm.util;bundle-version="7.0.0",
org.eclipse.core.filesystem;bundle-version="1.7.0"
Eclipse-LazyStart: true
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Automatic-Module-Name: org.eclipse.jdt.bcoview
<html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>About</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>About</title>
</head>
<body>
<body lang="EN-US">
<h2>About This Content</h2>
<h2>JVM Instruction Reference</h2>
<p>November 30, 2017</p>
<h3>License</h3>
<p>
Code from Java Virtual Machine by
Jon Meyer &amp; Troy Downing Copyright (c) 1997 by O'Reilly &amp; Associates.
Reprinted with the permission of O'Reilly Media, Inc.
</p>
<p>
The Eclipse Foundation makes available all content in this plug-in
(&quot;Content&quot;). Unless otherwise indicated below, the Content
is provided to you under the terms and conditions of the Eclipse
Public License Version 2.0 (&quot;EPL&quot;). A copy of the EPL is
available at <a href="http://www.eclipse.org/legal/epl-2.0">http://www.eclipse.org/legal/epl-2.0</a>.
For purposes of the EPL, &quot;Program&quot; will mean the Content.
</p>
<p>
Packaging, cleanup, reformatting and XSL transformation
completed by Eugene Kuleshov (eu@javatx.org).
</p>
<p>
If you did not receive this Content directly from the Eclipse
Foundation, the Content is being redistributed by another party
(&quot;Redistributor&quot;) and different terms and conditions may
apply to your use of any object code in the Content. Check the
Redistributor's license that was provided with the Content. If no such
license exists, contact the Redistributor. Unless otherwise indicated
below, the terms and conditions of the EPL still apply to any source
code in the Content and such source code may be obtained at <a
href="http://www.eclipse.org/">http://www.eclipse.org</a>.
</p>
</body>
</html>
</html>
\ No newline at end of file
......@@ -15,10 +15,6 @@
<property name="lib" value="${basedir}/lib"/>
<property name="out.build" value="${out}/build"/>
<path id="saxon.classpath">
<fileset dir="${saxon.home}" includes="*.jar"/>
</path>
<tstamp><format property="plugin.date" pattern="yyyyMMddHHmm" /></tstamp>
<target name="get-git-revision">
......@@ -86,8 +82,8 @@
</scriptdef>
<target name="getasm" >
<property name="asmRoot" value="http://download.eclipse.org/tools/orbit/downloads/drops2/R20180905201904/repository/plugins" />
<property name="asmVersion" value="6.2.1.v20180823-1831" />
<property name="asmRoot" value="http://download.eclipse.org/tools/orbit/downloads/drops2/R20181128170323/repository/plugins" />
<property name="asmVersion" value="7.0.0.v20181030-2244" />
<mkdir dir="${lib}"/>
<getAndCheckLibrary
url="${asmRoot}/org.objectweb.asm_${asmVersion}.jar"
......@@ -175,8 +171,8 @@
</zip>
</target>
<target name="plugin" depends="jars,xslt">
<zip zipfile="${out}/${plugin.jar}">
<target name="plugin" depends="jars">
<zip zipfile="${out}/site/plugins/${plugin.jar}">
<zipfileset dir="${out}" includes="BytecodeOutlinesrc.zip"/>
<fileset dir=".">
<include name="icons/**/*"/>
......@@ -190,21 +186,20 @@
<fileset dir="${out.build}">
<include name="**/*"/>
</fileset>
<zipfileset dir="${out}/doc" includes="toc.xml,opcodes.html,ref-*.html" prefix="doc"/>
</zip>
</target>
<target name="feature" depends="plugin">
<jar zipfile="${out}/${feature.jar}">
<zip zipfile="${out}/site/features/${feature.jar}">
<fileset dir="${out}/site" includes="feature.xml"/>
</jar>
</zip>
</target>
<target name="site" depends="cleanOutput,feature">
<zip zipfile="${out}/${plugin.id}.update_${plugin.version}.zip">
<zipfileset dir="${out}/site" includes="site.xml"/>
<zipfileset dir="${out}" includes="${feature.jar}" prefix="features"/>
<zipfileset dir="${out}" includes="${plugin.jar}" prefix="plugins"/>
<zipfileset dir="${out}/site/features" includes="${feature.jar}" prefix="features"/>
<zipfileset dir="${out}/site/plugins" includes="${plugin.jar}" prefix="plugins"/>
</zip>
</target>
......@@ -221,12 +216,4 @@
</delete>
</target>
<target name="xslt" depends="init">
<mkdir dir="${out}/doc"/>
<xslt basedir="." destdir="${out}/doc" includes="opcodes.xml" classpathref="saxon.classpath"
style="opcodes-doc.xsl" force="true">
<factory name="net.sf.saxon.TransformerFactoryImpl" />
</xslt>
</target>
</project>
This diff is collapsed.
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
exclude-result-prefixes="xsl fo">
<xsl:output method="html" indent="no" omit-xml-declaration="yes" encoding="UTF-8"/>
<xsl:template match="opcodes">
<html>
<xsl:comment>
</xsl:comment>
<body>
<!-- TOC -->
<xsl:for-each select='opcode'>
<xsl:sort/>
<xsl:variable name='nm' select='name/text()'/>
<a><xsl:attribute name='href'>#<xsl:value-of select="name/text()"/></xsl:attribute><xsl:value-of select="name/text()"/></a>
<xsl:value-of select="string( ' ')"/>
</xsl:for-each>
<hr/>
<!-- Details -->
<xsl:apply-templates select="*">
<xsl:sort/>
</xsl:apply-templates>
</body>
</html>
</xsl:template>
<xsl:template match="opcode">
<dl>
<dt>
<a><xsl:attribute name='name'><xsl:value-of select="name"/></xsl:attribute></a>
<b><xsl:value-of select="name"/></b> :
<xsl:apply-templates select="short/text()"/>
</dt>
<xsl:apply-templates select="desc"/>
<xsl:apply-templates select="exceptions"/>
<xsl:apply-templates select="example"/>
<xsl:apply-templates select="note"/>
<xsl:apply-templates select="see"/>
<xsl:apply-templates select="stack"/>
<xsl:apply-templates select="bytecode"/>
</dl>
<hr/>
</xsl:template>
<!-- Sections -->
<xsl:template match="stack">
<dt><i>Stack</i></dt>
<dd><xsl:apply-templates select="*|text()"/></dd>
</xsl:template>
<xsl:template match="desc">
<dt><i>Description</i></dt>
<dd><xsl:apply-templates select="*|text()"/></dd>
</xsl:template>
<xsl:template match="bytecode">
<dt><i>Bytecode</i></dt>
<dd><xsl:apply-templates select="*|text()"/></dd>
</xsl:template>
<xsl:template match="example">
<dt><i>Example</i></dt>
<dd><xsl:apply-templates select="*|text()"/></dd>
</xsl:template>
<xsl:template match="note">
<dt><i>Notes</i></dt>
<dd><xsl:apply-templates select="*|text()"/></dd>
</xsl:template>
<xsl:template match="see">
<dt><i>See also</i></dt>
<dd>
<xsl:call-template name="seeFormat"><xsl:with-param name="string" select="text()"/></xsl:call-template>
</dd>
</xsl:template>
<xsl:template match="exceptions">
<dt><i>Exceptions</i></dt>
<dd><xsl:apply-templates select="*|text()"/></dd>
</xsl:template>
<!-- Formatting -->
<xsl:template match="table">
<table border="1" cellspacing="0" cellpadding="3">
<xsl:apply-templates select="*"/>
</table>
</xsl:template>
<xsl:template match='text()'>
<xsl:call-template name="docFormat"><xsl:with-param name="string" select="."/></xsl:call-template>
</xsl:template>
<xsl:template name="docFormat">
<xsl:param name="string"/>
<!-- double CRLF will be replaced with <BR><BR> -->
<xsl:choose>
<xsl:when test="contains($string, '&#xA;&#xA;')">
<xsl:value-of select="substring-before($string, '&#xA;&#xA;')"/>
<br/>
<xsl:call-template name="docFormat">
<xsl:with-param name="string" select="substring-after($string, '&#xA;&#xA;')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="seeFormat">
<xsl:param name="string"/>
<xsl:choose>
<xsl:when test="contains($string, ',')">
<a>
<xsl:attribute name="href">#<xsl:value-of select="normalize-space(substring-before($string, ','))"/></xsl:attribute>
<xsl:value-of select="normalize-space(substring-before($string, ','))"/>
</a>
<xsl:value-of select="string( ' ')"/>
<xsl:call-template name="seeFormat">
<xsl:with-param name="string" select="substring-after($string, ',')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<a>
<xsl:attribute name="href">#<xsl:value-of select="normalize-space($string)"/></xsl:attribute>
<xsl:value-of select="normalize-space($string)"/>
</a>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Copy everything else -->
<xsl:template match='*|@*'>
<xsl:copy>
<xsl:apply-templates select='node()|@*'/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
......@@ -7,37 +7,25 @@
name="Bytecode"
icon="icons/bytecodeview.gif"
category="org.eclipse.jdt.ui.java"
class="de.loskutov.bco.views.BytecodeOutlineView"
id="de.loskutov.bco.views.BytecodeOutlineView"/>
class="org.eclipse.jdt.bcoview.views.BytecodeOutlineView"
id="org.eclipse.jdt.bcoview.views.BytecodeOutlineView"/>
<view
name="Bytecode Reference"
icon="icons/reference.gif"
category="org.eclipse.jdt.ui.java"
class="de.loskutov.bco.views.BytecodeReferenceView"
id="de.loskutov.bco.views.BytecodeReferenceView"/>
class="org.eclipse.jdt.bcoview.views.BytecodeReferenceView"
id="org.eclipse.jdt.bcoview.views.BytecodeReferenceView"/>
</extension>
<!--
<extension
point="org.eclipse.ui.preferencePages">
<page
category="org.eclipse.jdt.ui.preferences.JavaBasePreferencePage"
class="de.loskutov.bco.preferences.BCOPreferencePage"
id="BCOPreferencePage"
name="Bytecode Outline">
</page>
</extension>
-->
<extension point="org.eclipse.core.runtime.preferences">
<initializer class="de.loskutov.bco.preferences.BCOPreferenceInitializer"/>
<initializer class="org.eclipse.jdt.bcoview.preferences.BCOPreferenceInitializer"/>
</extension>
<extension
point="org.eclipse.ui.popupMenus">
<objectContribution
objectClass="org.eclipse.jdt.core.IOpenable"
id="de.loskutov.bco.CompareBytecodeActionContribution1">
id="org.eclipse.jdt.bcoview.CompareBytecodeActionContribution1">
<visibility>
<or>
......@@ -58,24 +46,24 @@
enablesFor="1"
label="Another Class Bytecode"
icon="icons/bytecodeview.gif"
class="de.loskutov.bco.ui.actions.OpenAction"
class="org.eclipse.jdt.bcoview.ui.actions.OpenAction"
menubarPath="compareWithMenu/compareWithGroup"
id="de.loskutov.bco.CompareBytecodeAction">
id="org.eclipse.jdt.bcoview.CompareBytecodeAction">
</action>
<action
enablesFor="2"
label="Each Other Bytecode"
icon="icons/bytecodeview.gif"
class="de.loskutov.bco.ui.actions.CompareBytecodeAction"
class="org.eclipse.jdt.bcoview.ui.actions.CompareBytecodeAction"
menubarPath="compareWithMenu/compareWithGroup"
id="de.loskutov.bco.OpenAction">
id="org.eclipse.jdt.bcoview.OpenAction">
</action>
</objectContribution>
<objectContribution
objectClass="org.eclipse.core.resources.IFile"
nameFilter="*.class"
id="de.loskutov.bco.CompareBytecodeActionContribution2">
id="org.eclipse.jdt.bcoview.CompareBytecodeActionContribution2">
<visibility>
<not>
......@@ -98,24 +86,24 @@
enablesFor="1"
label="Another Class Bytecode"
icon="icons/bytecodeview.gif"
class="de.loskutov.bco.ui.actions.OpenAction"
class="org.eclipse.jdt.bcoview.ui.actions.OpenAction"
menubarPath="compareWithMenu/compareWithGroup"
id="de.loskutov.bco.CompareBytecodeAction">
id="org.eclipse.jdt.bcoview.CompareBytecodeAction">
</action>
<action
enablesFor="2"
label="Each Other Bytecode"
icon="icons/bytecodeview.gif"
class="de.loskutov.bco.ui.actions.CompareBytecodeAction"
class="org.eclipse.jdt.bcoview.ui.actions.CompareBytecodeAction"
menubarPath="compareWithMenu/compareWithGroup"
id="de.loskutov.bco.OpenAction">
id="org.eclipse.jdt.bcoview.OpenAction">
</action>
</objectContribution>
<objectContribution
objectClass="org.eclipse.jdt.core.IMember"
nameFilter="*"
id="de.loskutov.bco.CompareBytecodeActionContribution3">
id="org.eclipse.jdt.bcoview.CompareBytecodeActionContribution3">
<visibility>
<not>
......@@ -138,9 +126,9 @@
enablesFor="2"
label="Each Other Bytecode"
icon="icons/bytecodeview.gif"
class="de.loskutov.bco.ui.actions.CompareMemberBytecodeAction"
class="org.eclipse.jdt.bcoview.ui.actions.CompareMemberBytecodeAction"
menubarPath="compareWithMenu/compareWithGroup"
id="de.loskutov.bco.OpenAction">
id="org.eclipse.jdt.bcoview.OpenAction">
</action>
</objectContribution>
......@@ -149,16 +137,16 @@
<extension
point="org.eclipse.ui.popupMenus">
<viewerContribution
targetID="de.loskutov.bco.views.BytecodeOutlineView#ContextMenu"
id="de.loskutov.bco.OpenBytecodeReference">
targetID="org.eclipse.jdt.bcoview.views.BytecodeOutlineView#ContextMenu"
id="org.eclipse.jdt.bcoview.OpenBytecodeReference">
<action
enablesFor="*"
label="Open bytecode reference"
icon="icons/reference.gif"
class="de.loskutov.bco.ui.actions.OpenBytecodeReferenceAction"
class="org.eclipse.jdt.bcoview.ui.actions.OpenBytecodeReferenceAction"
menubarPath="additions"
id="de.loskutov.bco.OpenReferenceAction"/>
id="org.eclipse.jdt.bcoview.OpenReferenceAction"/>
</viewerContribution>
</extension>
......@@ -169,74 +157,20 @@
<view
relative="org.eclipse.ui.views.ContentOutline"
visible="false"
id="de.loskutov.bco.views.BytecodeOutlineView"
id="org.eclipse.jdt.bcoview.views.BytecodeOutlineView"
relationship="stack">
</view>
<viewShortcut id="de.loskutov.bco.views.BytecodeOutlineView"/>
<viewShortcut id="org.eclipse.jdt.bcoview.views.BytecodeOutlineView"/>
</perspectiveExtension>
</extension>
<extension
point="org.eclipse.ui.editors">
<editor
class="de.loskutov.bco.editors.BytecodeClassFileEditor"
contributorClass="de.loskutov.bco.editors.BytecodeActionBarContributor"
default="false"
extensions="class"
icon="icons/bytecodeview.gif"
id="de.loskutov.bco.editors.BytecodeClassFileEditor"
name="Class File Bytecode Viewer"
symbolicFontName="org.eclipse.jdt.ui.editors.textfont">
<contentTypeBinding contentTypeId="org.eclipse.jdt.core.javaClass"/>
</editor>
<editor
class="de.loskutov.bco.editors.BytecodeClassFileEditor"
contributorClass="de.loskutov.bco.editors.BytecodeActionBarContributor"
default="true"
filenames="*.class without source"
icon="icons/bytecodeview.gif"
id="de.loskutov.bco.editors.BytecodeClassFileEditorNoSource"
name="Class File Bytecode Viewer"
symbolicFontName="org.eclipse.jdt.ui.editors.textfont">
</editor>
</extension>
<!-- replacement for org.eclipse.debug.ui.actions.RulerToggleBreakpointActionDelegate,
required for toggle breakpoint by double-click in editor ruler in class files -->
<extension
point="org.eclipse.ui.editorActions">
<editorContribution
targetID="de.loskutov.bco.editors.BytecodeClassFileEditor"
id="de.loskutov.bco.editors.BreakpointRulerActions">
<action
label="?"
class="org.eclipse.debug.ui.actions.RulerToggleBreakpointActionDelegate"
style="push"
actionID="RulerDoubleClick"
id="de.loskutov.bco.editors.ManageBreakpointRulerAction">
</action>
</editorContribution>
</extension>
<extension point="org.eclipse.help.toc">
<toc file="doc/toc.xml" primary="true" />
</extension>
<!-- because of org.eclipse.jdt.internal.ui.javaeditor.ClassFileEditor replacement
<extension point="org.eclipse.core.runtime.adapters">
<factory
class="org.eclipse.jdt.internal.debug.ui.actions.RetargettableActionAdapterFactory"
adaptableType="de.loskutov.bco.editors.BytecodeClassFileEditor">
<adapter type="org.eclipse.debug.ui.actions.IRunToLineTarget"/>
<adapter type="org.eclipse.debug.ui.actions.IToggleBreakpointsTarget"/>
</factory>
</extension> -->
<extension
point="org.eclipse.ui.preferencePages">
<page
category="org.eclipse.jdt.ui.preferences.JavaBasePreferencePage"
class="de.loskutov.bco.preferences.BCOPreferencePage"
id="de.loskutov.ByteCodeOutline.page"
class="org.eclipse.jdt.bcoview.preferences.BCOPreferencePage"
id="org.eclipse.jdt.bcoview.ByteCodeOutline.page"
name="Bytecode Outline">
</page>
</extension>
......
<?xml version="1.0" encoding="UTF-8"?>
<feature
id="de.loskutov.BytecodeOutline.feature"
id="org.eclipse.jdt.bcoview.feature"
label="Bytecode Outline"
version="@FEATURE_VERSION@"
provider-name="Andrey Loskutov"
plugin="de.loskutov.BytecodeOutline">
plugin="org.eclipse.jdt.bcoview">
<description url="http://asm.ow2.org/eclipse/index.html">
Bytecode outline and bytecode comparison view for java/class files.
</description>
<copyright url="..">
Copyright (C)2004-2017 by Andrey Loskutov Loskutov@gmx.de
All rights reserved.
Copyright (c) 2004-2018 by Andrey Loskutov Loskutov@gmx.de
All rights reserved.
</copyright>
<license>
Copyright (C)2004-2017 by Andrey Loskutov Loskutov@gmx.de
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS&apos;&apos; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<license url="https://www.eclipse.org/legal/epl-2.0/">
Copyright (c) 2004 - 2018 Andrey Loskutov, licensed under the Eclipse Public License 2.0.
</license>
<url>
<update label="ObjectWeb update site" url="http://download.forge.objectweb.org/eclipse-update/"/>
<discovery label="ObjectWeb update site" url="http://download.forge.objectweb.org/eclipse-update/"/>
<discovery label="Andrey Loskutov plugins" url="http://andrei.gmxhome.de/eclipse/"/>
</url>
......@@ -51,7 +40,7 @@ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS&apos;&apos; AND
</requires>
<plugin
id="de.loskutov.BytecodeOutline"
id="org.eclipse.jdt.bcoview"
download-size="710"
install-size="710"
version="@PLUGIN_VERSION@"
......
......@@ -39,9 +39,9 @@
<archive path="plugins/de.loskutov.BytecodeOutline_2.4.3.jar" url="http://download.forge.objectweb.org/asm/de.loskutov.BytecodeOutline_2.4.3.jar"/>
<category-def name="Bytecode Outline for Eclipse 3.6-4.4" label="Bytecode Outline for Eclipse 3.6-4.4"/>
<feature url="features/de.loskutov.BytecodeOutline.feature_@FEATURE_VERSION@.jar" id="de.loskutov.BytecodeOutline.feature" version="@FEATURE_VERSION@">
<category name="Bytecode Outline for Eclipse 4.7-4.8"/>
<feature url="features/org.eclipse.jdt.bcoview.feature_@FEATURE_VERSION@.jar" id="org.eclipse.jdt.bcoview.feature" version="@FEATURE_VERSION@">
<category name="Bytecode Outline for Eclipse 4.7-4.10"/>
</feature>
<category-def name="Bytecode Outline for Eclipse 4.7-4.8" label="Bytecode Outline for Eclipse 4.7-4.8"/>
<category-def name="Bytecode Outline for Eclipse 4.7-4.10" label="Bytecode Outline for Eclipse 4.7-4.10"/>
</site>
package de.loskutov.bco.asm;
/**
* @author Andrei
*/
public class LineRange {
public final int startLine;
public final int endLine;
public LineRange(int startLine, int endLine) {
super();
this.startLine = startLine;
this.endLine = endLine;
}
}
package de.loskutov.bco.editors;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.ClasspathContainerInitializer;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.ui.javaeditor.ClassFileEditorActionContributor;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.BuildPathSupport;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListElement;
import org.eclipse.jdt.ui.wizards.BuildPathDialogAccess;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import de.loskutov.bco.BytecodeOutlinePlugin;
import de.loskutov.bco.preferences.BCOConstants;
/**
* Adds "Show Bytecode" action to tool/menu bars
* @author V. Grishchenko, Eugene Kuleshov, Andrei
*/
public class BytecodeActionBarContributor
extends
ClassFileEditorActionContributor {
BytecodeClassFileEditor editor;
protected ShowBytecodeAction refreshAction;
protected ToggleRawBytecodeAction toggleRawBytecodeAction;
private final AttachSourceAction attachAction;
public BytecodeActionBarContributor() {
super();
String symbolicName = BytecodeOutlinePlugin.getDefault().getBundle()
.getSymbolicName();
ImageDescriptor actionIcon = AbstractUIPlugin
.imageDescriptorFromPlugin(symbolicName, "icons/bytecodeview.gif");
refreshAction = new ShowBytecodeAction(actionIcon);
actionIcon = AbstractUIPlugin.imageDescriptorFromPlugin(
symbolicName, "icons/raw_mode.gif");
toggleRawBytecodeAction = new ToggleRawBytecodeAction(actionIcon);
actionIcon = AbstractUIPlugin.imageDescriptorFromPlugin(
symbolicName, "icons/source.gif");
attachAction = new AttachSourceAction(actionIcon);
}
@Override
public void contributeToToolBar(IToolBarManager toolBarManager) {
super.contributeToToolBar(toolBarManager);
toolBarManager.add(refreshAction);
toolBarManager.add(toggleRawBytecodeAction);
toolBarManager.add(attachAction);
// toolBarManager.add(new Separator(JadclipsePlugin.PID_JADCLIPSE));
// toolBarManager.appendToGroup(JadclipsePlugin.PID_JADCLIPSE, dAction);
}
@Override
public void contributeToMenu(IMenuManager menu) {
super.contributeToMenu(menu);
IMenuManager edit = menu
.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
if (edit != null) {
edit.add(refreshAction);
edit.add(toggleRawBytecodeAction);
edit.add(attachAction);
}
}
@Override
public void setActiveEditor(IEditorPart targetEditor) {
if (targetEditor instanceof BytecodeClassFileEditor) {
editor = (BytecodeClassFileEditor) targetEditor;
refreshAction.setEnabled(editor.hasMappedSource());
refreshAction.setChecked(editor.isDecompiled());
toggleRawBytecodeAction.setEnabled(editor.isDecompiled());
toggleRawBytecodeAction.setChecked(editor
.getDecompilerFlag(BCOConstants.F_SHOW_RAW_BYTECODE));
attachAction.setEnabled(editor.isSourceAttachmentPossible());
} else {
refreshAction.setEnabled(false);
toggleRawBytecodeAction.setEnabled(false);
attachAction.setEnabled(false);
editor = null;
}
super.setActiveEditor(targetEditor);
}
private class ShowBytecodeAction extends Action {
protected ShowBytecodeAction(ImageDescriptor actionIcon) {
super("Show Bytecode@Ctrl+Shift+B", SWT.TOGGLE);
setImageDescriptor(actionIcon);
setToolTipText("Show Bytecode");
setAccelerator(SWT.CTRL | SWT.SHIFT | 'B');
}
@Override
public void run() {
if (editor != null) {
ISelection selection = editor.getSelectionProvider()
.getSelection();
boolean showBytecode = isChecked();
if (editor.isDecompiled() != showBytecode) {
editor.doSetInput(true, !showBytecode);
if (selection instanceof ITextSelection) {
ITextSelection textSelection = (ITextSelection) selection;
textSelection = editor.convertSelection(
textSelection, showBytecode);
editor.getSelectionProvider().setSelection(
textSelection);
}
}
toggleRawBytecodeAction.setEnabled(editor.isDecompiled());
}
}
}
private class AttachSourceAction extends Action {
protected AttachSourceAction(ImageDescriptor actionIcon) {
super("Attach Source...", SWT.NONE);
setImageDescriptor(actionIcon);
setToolTipText("Attach Source...");
}
@Override
public void run() {
if (editor == null) {
return;
}
IPackageFragmentRoot root = editor.getPackageFragmentRoot(editor.getClassFile());
try {
IClasspathEntry entry = root.getRawClasspathEntry();
IPath containerPath = null;
IJavaProject javaProject = root.getJavaProject();
if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
containerPath = entry.getPath();
IClasspathContainer container = JavaCore
.getClasspathContainer(containerPath, javaProject);
if(!isSourceAttachmentPossible(containerPath, javaProject)){
editor.setSourceAttachmentPossible(false);
attachAction.setEnabled(false);
BytecodeOutlinePlugin
.error("Unable to configure source attachment:\n"
+ "classpath entry '" + containerPath +
"'\nis either read-only "
+ "or source attachment is not supported...", null);
return;
}
entry = JavaModelUtil.findEntryInContainer(container, root
.getPath());
}
Shell shell = Display.getDefault().getActiveShell();
IClasspathEntry cpe = BuildPathDialogAccess
.configureSourceAttachment(shell, entry);
if (cpe == null) {
return;
}
String[] changedAttributes = {CPListElement.SOURCEATTACHMENT};
BuildPathSupport.modifyClasspathEntry(
shell, cpe, changedAttributes, javaProject, containerPath,
cpe.getReferencingEntry() != null,
new NullProgressMonitor());
} catch (CoreException e) {
BytecodeOutlinePlugin.error(
"Unable to configure source attachment", e);
}
}
private boolean isSourceAttachmentPossible(IPath containerPath,
IJavaProject javaProject) {
ClasspathContainerInitializer initializer = JavaCore
.getClasspathContainerInitializer(containerPath
.segment(0));
IStatus status = initializer.getSourceAttachmentStatus(
containerPath, javaProject);
if (status.getCode() == ClasspathContainerInitializer.ATTRIBUTE_NOT_SUPPORTED
|| status.getCode() == ClasspathContainerInitializer.ATTRIBUTE_READ_ONLY) {
return false;
}
return true;
}
}
private class ToggleRawBytecodeAction extends Action {
protected ToggleRawBytecodeAction(ImageDescriptor actionIcon) {
super("Show Internal Types", SWT.TOGGLE);
setImageDescriptor(actionIcon);
setToolTipText("Show Internal Types");
}
@Override
public void run() {
if (editor != null) {
editor.setDecompilerFlag(
BCOConstants.F_SHOW_RAW_BYTECODE, isChecked());
ISelection selection = editor.getSelectionProvider()
.getSelection();
// we convert selection first to source line bacause bytecode lines could
// not match for different bytecode view modes.
int sourceLine = 0;
if (selection instanceof ITextSelection) {
sourceLine = editor.getSourceLine((ITextSelection) selection);
}
editor.doSetInput(true, false);
if (selection instanceof ITextSelection) {
ITextSelection textSelection = editor.convertLine(sourceLine);
if(textSelection != null) {
editor.getSelectionProvider().setSelection(textSelection);
}
}
}
}
}
}
package de.loskutov.bco.editors;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.debug.core.IJavaMethodBreakpoint;
import org.eclipse.jdt.debug.core.IJavaWatchpoint;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.internal.debug.ui.actions.BreakpointLocationVerifierJob;
import org.eclipse.jdt.internal.debug.ui.actions.ToggleBreakpointAdapter;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPart;
/**
* Extend ToggleBreakpointAdapter to allow us map source code lines to the bytecode lines
* TODO implement the mapping :)
* @author Andrei
*/
public class BytecodeBreakpointAdapter extends ToggleBreakpointAdapter {
public boolean canToggleBreakpoints(IWorkbenchPart part,
ISelection selection) {
// should work for us.
return super.canToggleBreakpoints(part, selection);
}
public void toggleBreakpoints(IWorkbenchPart part, ISelection selection)
throws CoreException {
// should work for us.
super.toggleBreakpoints(part, selection);
}
public boolean canToggleLineBreakpoints(IWorkbenchPart part,
ISelection selection) {
// should work for us.
return super.canToggleBreakpoints(part, selection);
}
public boolean canToggleMethodBreakpoints(IWorkbenchPart part,
ISelection selection) {
// TODO should revisit, because it deals with IJavaElements in the selection
return super.canToggleMethodBreakpoints(part, selection);
}
public boolean canToggleWatchpoints(IWorkbenchPart part,
ISelection selection) {
// TODO should revisit, because it deals with IJavaElements in the selection
return super.canToggleWatchpoints(part, selection);
}
public void toggleLineBreakpoints(IWorkbenchPart part, ISelection selection)
throws CoreException {
// should work for us.
super.toggleLineBreakpoints(part, selection);
}
public void toggleMethodBreakpoints(final IWorkbenchPart part,
final ISelection finalSelection) {
if(part instanceof BytecodeClassFileEditor){
BytecodeClassFileEditor classEditor = (BytecodeClassFileEditor) part;
if(classEditor.isDecompiled()){
return;
}
super.toggleMethodBreakpoints(part, finalSelection);
}
}
/**
* Toggles a line breakpoint. This is also the method called by the keybinding for creating breakpoints
* @param part the currently active workbench part
* @param selection the current selection
* @param bestMatch if we should make a best match or not
*/
public void toggleLineBreakpoints(final IWorkbenchPart part, final ISelection selection, final boolean bestMatch) {
if(part instanceof BytecodeClassFileEditor){
BytecodeClassFileEditor classEditor = (BytecodeClassFileEditor) part;
if(classEditor.isDecompiled()){
return;
}
super.toggleLineBreakpoints(part, selection, bestMatch);
}
}
/**
* Returns any existing method breakpoint for the specified method or <code>null</code> if none.
*
* @param typeName fully qualified type name
* @param methodName method selector
* @param methodSignature method signature
* @return existing method or <code>null</code>
* @throws CoreException
*/
protected IJavaMethodBreakpoint getMethodBreakpoint(String typeName, String methodName, String methodSignature) throws CoreException {
final IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager();
IBreakpoint[] breakpoints = breakpointManager.getBreakpoints(JDIDebugModel.getPluginIdentifier());
for (int i = 0; i < breakpoints.length; i++) {
IBreakpoint breakpoint = breakpoints[i];
if (breakpoint instanceof IJavaMethodBreakpoint) {
final IJavaMethodBreakpoint methodBreakpoint = (IJavaMethodBreakpoint) breakpoint;
if (typeName.equals(methodBreakpoint.getTypeName()) && methodName.equals(methodBreakpoint.getMethodName()) && methodSignature.equals(methodBreakpoint.getMethodSignature())) {
return methodBreakpoint;
}
}
}
return null;
}
/**
* Returns any existing watchpoint for the given field, or <code>null</code> if none.
*
* @param typeName fully qualified type name on which watchpoint may exist
* @param fieldName field name
* @return any existing watchpoint for the given field, or <code>null</code> if none
* @throws CoreException
*/
protected IJavaWatchpoint getWatchpoint(String typeName, String fieldName) throws CoreException {
IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager();
IBreakpoint[] breakpoints = breakpointManager.getBreakpoints(JDIDebugModel.getPluginIdentifier());
for (int i = 0; i < breakpoints.length; i++) {
IBreakpoint breakpoint = breakpoints[i];
if (breakpoint instanceof IJavaWatchpoint) {
IJavaWatchpoint watchpoint = (IJavaWatchpoint) breakpoint;
if (typeName.equals(watchpoint.getTypeName()) && fieldName.equals(watchpoint.getFieldName())) {
return watchpoint;
}
}
}
return null;
}
protected void createMethodBreakpoint(IResource resource, String typeName, String methodName, String methodSignature, boolean entry, boolean exit, boolean nativeOnly, int lineNumber, int charStart, int charEnd, int hitCount, boolean register, Map attributes) throws CoreException {
JDIDebugModel.createMethodBreakpoint(resource, typeName, methodName, methodSignature, entry, exit, nativeOnly, lineNumber, charStart, charEnd, hitCount, register, attributes);
}
protected void createWatchpoint(IResource resource, String typeName, String fieldName, int lineNumber, int charStart, int charEnd, int hitCount, boolean register, Map attributes) throws CoreException {
JDIDebugModel.createWatchpoint(resource, typeName, fieldName, lineNumber, charStart, charEnd, hitCount, register, attributes);
}
protected void createLineBreakpoint(IResource resource, String typeName, int lineNumber, int charStart, int charEnd, int hitCount, boolean register, Map attributes, IDocument document, boolean bestMatch, IType type, IEditorPart editorPart) throws CoreException {
IJavaLineBreakpoint breakpoint = JDIDebugModel.createLineBreakpoint(resource, typeName, lineNumber, charStart, charEnd, hitCount, register, attributes);
new BreakpointLocationVerifierJob(document, breakpoint, lineNumber, bestMatch, typeName, type, resource, editorPart).schedule();
}
/**
* Removes the specified breakpoint
* @param breakpoint the breakpoint to remove
* @param delete if it should be deleted as well
* @throws CoreException
*/
protected void removeBreakpoint(IBreakpoint breakpoint, boolean delete) throws CoreException {
DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(breakpoint, delete);
}
/**
* Returns if the structured selection is itself or is part of an interface
* @param selection the current selection
* @return true if the selection isor is part of an interface, false otherwise
* @since 3.2
*/
protected boolean isInterface(ISelection selection) {
if (!selection.isEmpty()) {
try {
if(selection instanceof IStructuredSelection) {
IStructuredSelection ss = (IStructuredSelection) selection;
Iterator iterator = ss.iterator();
IType type = null;
Object obj = null;
while (iterator.hasNext()) {
obj = iterator.next();
if(obj instanceof IMember) {
type = ((IMember)obj).getDeclaringType();
}
if(type != null && type.isInterface()) {
return true;
}
}
}
else if(selection instanceof ITextSelection) {
ITextSelection tsel = (ITextSelection) selection;
IType type = getType(tsel);
if(type != null && type.isInterface()) {
return true;
}
}
}
catch (JavaModelException e) {JDIDebugUIPlugin.log(e);}
}
return false;
}
}
package de.loskutov.bco.editors;
import java.lang.reflect.Method;
import org.eclipse.jdt.core.IBuffer;
import org.eclipse.jdt.core.IOpenable;
import org.eclipse.jdt.internal.core.BufferManager;
/**
* This class is a hack that mades JDT <code>BufferManager</code> methods
* <code>addBuffer()</code> and <code>removeBuffer()</code> accessible.
*
* It does NOT modify or replace the instance of default buffer manager, because if they
* are more then one plugin which performs such hack, then it will end up in a big bang.
*
* @author Andrei
*/
public final class BytecodeBufferManager {
private BytecodeBufferManager() {
super();
}
public static IBuffer getBuffer(IOpenable owner) {
return BufferManager.getDefaultBufferManager().getBuffer(owner);
}
public static IBuffer createBuffer(IOpenable owner) {
BufferManager.getDefaultBufferManager();
return BufferManager.createBuffer(owner);
}
/**
* @see BufferManager#addBuffer(IBuffer)
*/
public static void addBuffer(IBuffer buffer) {
BufferManager manager = BufferManager.getDefaultBufferManager();
try {
Method addMethod = BufferManager.class.getDeclaredMethod(
"addBuffer", new Class[]{IBuffer.class});
addMethod.setAccessible(true);
addMethod.invoke(manager, new Object[]{buffer});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* @see BufferManager#removeBuffer(IBuffer)
*/
public static void removeBuffer(IBuffer buffer) {
if (buffer != null) {
BufferManager manager = BufferManager.getDefaultBufferManager();
try {
Method removeMethod = BufferManager.class.getDeclaredMethod(
"removeBuffer", new Class[]{IBuffer.class});
removeMethod.setAccessible(true);
removeMethod.invoke(manager, new Object[]{buffer});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package de.loskutov.bco.editors;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.IBuffer;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.IOrdinaryClassFile;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.BufferManager;
import org.eclipse.jdt.internal.ui.javaeditor.ClassFileDocumentProvider;
import org.eclipse.jdt.internal.ui.javaeditor.IClassFileEditorInput;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PlatformUI;
import de.loskutov.bco.BytecodeOutlinePlugin;
/**
* Overriden to get control over document content for bytecode editors
* @author Andrei
*/
public class BytecodeDocumentProvider extends ClassFileDocumentProvider {
public BytecodeDocumentProvider(BytecodeClassFileEditor classFileEditor) {
super();
}
/*
* Overriden to get control over document content for bytecode editors
* @see StorageDocumentProvider#setDocumentContent(IDocument, IEditorInput)
*/
@Override
protected boolean setDocumentContent(IDocument document,
IEditorInput editorInput, String encoding) throws CoreException {
if (editorInput instanceof IClassFileEditorInput) {
IClassFile classFile = ((IClassFileEditorInput) editorInput)
.getClassFile();
String source = null;
try {
source = classFile.getSource();
} catch (JavaModelException e) {
// ignore, this may happen if *class* file is not on class path but inside
// of source tree without associated source
}
if (source == null) {
// this could be the case for class files which are not on the class path
// buffer should be already opened and created in our editor->doOpenBuffer
// method
IBuffer buffer = BufferManager.getDefaultBufferManager().getBuffer(classFile);
if (buffer != null) {
source = buffer.getContents();
}
}
document.set(source);
return true;
}
return super.setDocumentContent(document, editorInput, encoding);
}
/**
*
* During DEBUG session, debugger tries to get line information for the current line
* in the stack, and then uses this info to set cursor and select text in editor.
*
* The problem is, that Java debugger knows only "source" - based lines, but our editor
* contains "bytecode" text, where the lines are NOT aligned to the source code lines.
* (it is simply not possible).
*
* So if we do not change the default implementation, the selected bytecode text will
* never match requested sourcecode lines.
*
* As workaround we "just" pass to the debugger another document, as one we use to
* represent the text in our editor. This document is a proxy and just replaces
* the implementation of "getLineInformation" method. Our implementation mapps the
* requested sourcecode line to the bytecode line in editor.
*
* All other clients of this method shouldn't be affected and should receive always
* the original document.
*/
@Override
public IDocument getDocument(Object element) {
IDocument document = super.getDocument(element);
if (element instanceof IClassFileEditorInput && isDebuggerCall()) {
IClassFileEditorInput input = (IClassFileEditorInput) element;
return new DocumentProxy4Debugger(document, input.getClassFile());
}
return document;
}
/**
* We are looking for two stack patterns, which both are related to DEBUG session and
* coming from SourceLookupFacility.display(ISourceLookupResult result, IWorkbenchPage page):
* first is the highlighting the editor current line, corresponding to
* the line in the bytecode stack (light gray color),
* and second is the annotation the current debugger position (same line as before) in
* editor (light green color)
*
* This is a VERY BAD and VERY DIRTY hack, but it works.
* @return
*/
private static boolean isDebuggerCall() {
Exception e = new Exception();
StackTraceElement[] stackTrace = e.getStackTrace();
boolean stackOk = true;
// at 0 is our method name, and 1 id the "getDocument" call, so we start with 2
for (int i = 2; i < stackTrace.length; i++) {
StackTraceElement elt = stackTrace[i];
switch (i) {
case 2 :
stackOk = "getLineInformation".equals(elt.getMethodName())
|| "addAnnotation".equals(elt.getMethodName());
break;
case 3 :
stackOk = "positionEditor".equals(elt.getMethodName())
|| "display".equals(elt.getMethodName());
break;
default :
break;
}
if(! stackOk || i > 3){
return false;
}
if (stackOk && i == 3) {
IEditorPart activeEditor = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow().getActivePage()
.getActiveEditor();
if(activeEditor instanceof BytecodeClassFileEditor){
BytecodeClassFileEditor editor = (BytecodeClassFileEditor) activeEditor;
return editor.isDecompiled();
}
}
}
return false;
}
public IRegion getDecompiledLineInfo(IEditorInput input, int decompiledLine) {
IDocument document = getDocument(input);
try {
return document.getLineInformation(decompiledLine);
} catch (BadLocationException e) {
BytecodeOutlinePlugin.log(e, IStatus.ERROR);
}
return null;
}
/*
* SourceLookupFacility.class: The code is responsible for the
* positioning of current debugger line during debugging Positions the text editor for
* the given stack frame :
* private void positionEditor(ITextEditor editor, IStackFrame frame)
* private IRegion getLineInformation(ITextEditor editor, int lineNumber)
*
* Other place for DEBUG instruction pointer with the "wrong line" is InstructionPointerManager
* public void addAnnotation(ITextEditor textEditor, IStackFrame frame, Annotation annotation)
*/
/**
* This class is non-functional replacement for IDocument. The only one purpose is to
* override getLineInformation() implementation for DEBUG purposes
*/
private static final class DocumentProxy4Debugger extends AbstractDocument {
private final IDocument delegate;
private final IClassFile cf;
public DocumentProxy4Debugger(IDocument delegate, IClassFile cf) {
super();
this.delegate = delegate;
this.cf = cf;
}
@Override
public IRegion getLineInformation(int line) throws BadLocationException {
BytecodeSourceMapper mapper = BytecodeClassFileEditor
.getSourceMapper();
int decompiledLine;
if(line < -1){
/* this is the case if debugger does not have line information in bytecode
* if bytecode does not contain line info, we should at least
* return the line with the first method instruction.
*/
decompiledLine = mapper.mapDebuggerToDecompiled(cf);
} else {
// SourceLookupFacility decrement source line by 1
decompiledLine = mapper.mapToDecompiled(line + 1, cf);
if(decompiledLine == -1){
/*
* The line is from inner class (it is in another class file)
* the mapping does not work for inner/anon. classes, as the debugger
* expect that their source code is in our editor which is not the case for
* bytecode of inner classes => for inner classes we use another strategy
*/
if(cf instanceof IOrdinaryClassFile) {
return BytecodeClassFileEditor.checkForInnerClass(line, (IOrdinaryClassFile) cf);
}
}
}
// editor start lines with 1
return delegate.getLineInformation(decompiledLine + 1);
}
}
}
/*****************************************************************************************
* Copyright (c) 2011 Andrey Loskutov. All rights reserved. This program and the
* accompanying materials are made available under the terms of the BSD License which
* accompanies this distribution, and is available at
* http://www.opensource.org/licenses/bsd-license.php
* Contributor: Jochen Klein - initial API and implementation
* Contributor: Andrey Loskutov - fixes
****************************************************************************************/
package de.loskutov.bco.editors;
import java.util.BitSet;
import java.util.WeakHashMap;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.contexts.DebugContextEvent;
import org.eclipse.debug.ui.contexts.IDebugContextListener;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IOrdinaryClassFile;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.debug.core.IJavaReferenceType;
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
import org.eclipse.jdt.internal.core.BinaryType;
import org.eclipse.jdt.internal.debug.core.model.JDIStackFrame;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import de.loskutov.bco.BytecodeOutlinePlugin;
import de.loskutov.bco.asm.DecompiledClass;
import de.loskutov.bco.asm.DecompilerHelper;
import de.loskutov.bco.asm.DecompilerOptions;
import de.loskutov.bco.ui.JdtUtils;
/**
* @author Jochen Klein
* @author Andrei
*/
public class BytecodeSourceMapper implements IDebugContextListener {
/** key is IClassFile, value is DecompiledClass */
private final WeakHashMap<IClassFile, DecompiledClass> classToDecompiled;
private IJavaReferenceType lastTypeInDebugger;
private String lastMethodInDebugger;
public BytecodeSourceMapper() {
super();
classToDecompiled = new WeakHashMap<IClassFile, DecompiledClass>();
DebugUITools.getDebugContextManager().addDebugContextListener(this);
}
public char[] getSource(IOrdinaryClassFile classFile, BitSet decompilerFlags) {
IType type;
type = classFile.getType();
if (type == null || !type.isBinary()) {
return null;
}
IBinaryType info = null;
try {
info = (IBinaryType) ((BinaryType) type).getElementInfo();
} catch (JavaModelException e) {
BytecodeOutlinePlugin.log(e, IStatus.ERROR);
return null;
}
if (info == null) {
return null;
}
return findSource(type, info, classFile, decompilerFlags);
}
public char[] getSource(IClassFile cf, BitSet decompilerFlags) {
StringBuffer source