├── .project ├── .settings ├── org.eclipse.core.resources.prefs └── org.eclipse.m2e.core.prefs ├── .travis.yml ├── CodeLensJDTDemo.gif ├── CodeLensLSP4e.png ├── CodeLensStyledText.gif ├── CodeLensTypeScriptDemo.gif ├── LICENSE ├── README.md ├── javassist ├── .classpath ├── .gitignore ├── .project ├── .settings │ ├── org.eclipse.core.resources.prefs │ ├── org.eclipse.jdt.core.prefs │ └── org.eclipse.m2e.core.prefs ├── META-INF │ └── MANIFEST.MF ├── build.properties ├── lib │ └── javassist-3.11.jar └── pom.xml ├── org.eclipse.codelens.editors ├── .classpath ├── .gitignore ├── .project ├── .settings │ ├── org.eclipse.jdt.core.prefs │ └── org.eclipse.m2e.core.prefs ├── META-INF │ └── MANIFEST.MF ├── build.properties ├── plugin.properties ├── plugin.xml ├── pom.xml ├── schema │ └── codeLensControllerFactories.exsd └── src │ └── org │ └── eclipse │ └── codelens │ └── editors │ ├── AbstractCodeLensController.java │ ├── DefaultCodeLensController.java │ ├── EditorCodeLensContext.java │ ├── ICodeLensController.java │ ├── ICodeLensControllerFactory.java │ ├── IEditorCodeLensContext.java │ └── internal │ ├── CodeLensControllerRegistry.java │ ├── CodeLensEditorPlugin.java │ ├── CodeLensEditorStartup.java │ └── EditorTracker.java ├── org.eclipse.codelens.feature ├── .gitignore ├── .project ├── .settings │ └── org.eclipse.m2e.core.prefs ├── build.properties ├── epl-v10.html ├── feature.properties ├── feature.xml ├── license.html └── pom.xml ├── org.eclipse.codelens.jdt ├── .classpath ├── .gitignore ├── .project ├── .settings │ ├── org.eclipse.jdt.core.prefs │ └── org.eclipse.m2e.core.prefs ├── META-INF │ └── MANIFEST.MF ├── build.properties ├── plugin.properties ├── plugin.xml ├── pom.xml └── src │ └── org │ └── eclipse │ └── codelens │ └── jdt │ └── internal │ ├── JDTUtils.java │ ├── JavaCodeLens.java │ ├── JavaCodeLensController.java │ ├── JavaCodeLensControllerProvider.java │ └── JavaCodeLensProvider.java ├── org.eclipse.codelens.jface.fragment ├── .classpath ├── .gitignore ├── .project ├── .settings │ ├── org.eclipse.jdt.core.prefs │ └── org.eclipse.m2e.core.prefs ├── META-INF │ └── MANIFEST.MF ├── build.properties └── pom.xml ├── org.eclipse.codelens.lsp4e ├── .classpath ├── .gitignore ├── .project ├── .settings │ ├── org.eclipse.jdt.core.prefs │ └── org.eclipse.m2e.core.prefs ├── META-INF │ └── MANIFEST.MF ├── build.properties ├── plugin.properties ├── plugin.xml ├── pom.xml └── src │ └── org │ └── eclipse │ └── codelens │ └── lsp4e │ └── internal │ ├── LSPCodeLens.java │ ├── LSPCodeLensControllerProvider.java │ └── LSPCodeLensProvider.java ├── org.eclipse.codelens.repository ├── .classpath ├── .gitignore ├── .project ├── .settings │ ├── org.eclipse.jdt.core.prefs │ └── org.eclipse.m2e.core.prefs ├── category.xml └── pom.xml ├── org.eclipse.codelens.samples ├── .classpath ├── .gitignore ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs ├── META-INF │ └── MANIFEST.MF ├── build.properties └── src │ └── org │ └── eclipse │ └── codelens │ └── samples │ ├── ClassCodeLens.java │ ├── ClassImplementationsCodeLensProvider.java │ ├── ClassReferencesCodeLensProvider.java │ ├── CodeLensDemo.java │ ├── StyledTextLineSpacingDemo.java │ └── ViewZoneDemo.java ├── org.eclipse.codelens.swt.fragment ├── .classpath ├── .gitignore ├── .project ├── .settings │ ├── org.eclipse.jdt.core.prefs │ └── org.eclipse.m2e.core.prefs ├── META-INF │ └── MANIFEST.MF ├── build.properties └── pom.xml ├── org.eclipse.codelens ├── .classpath ├── .gitignore ├── .project ├── .settings │ ├── org.eclipse.jdt.core.prefs │ └── org.eclipse.m2e.core.prefs ├── META-INF │ └── MANIFEST.MF ├── build.properties ├── plugin.properties ├── plugin.xml ├── pom.xml ├── schema │ └── codeLensProviders.exsd └── src │ └── org │ └── eclipse │ ├── codelens │ └── internal │ │ └── CodeLensPlugin.java │ ├── jface │ └── text │ │ ├── provisional │ │ ├── codelens │ │ │ ├── AbstractSyncCodeLensProvider.java │ │ │ ├── CodeLens.java │ │ │ ├── CodeLensProviderRegistry.java │ │ │ ├── CodeLensStrategy.java │ │ │ ├── Command.java │ │ │ ├── DefaultCodeLensContext.java │ │ │ ├── ICodeLens.java │ │ │ ├── ICodeLensContext.java │ │ │ ├── ICodeLensProvider.java │ │ │ ├── ICommand.java │ │ │ ├── Range.java │ │ │ └── internal │ │ │ │ ├── CodeLens.java │ │ │ │ ├── CodeLensData.java │ │ │ │ ├── CodeLensHelper.java │ │ │ │ └── CodeLensViewZone.java │ │ └── viewzones │ │ │ ├── DefaultViewZone.java │ │ │ ├── IViewZone.java │ │ │ ├── IViewZoneChangeAccessor.java │ │ │ ├── ViewZone.java │ │ │ └── ViewZoneChangeAccessor.java │ │ └── source │ │ └── patch │ │ └── LineNumberChangeRulerColumnPatch.java │ └── swt │ └── custom │ ├── patch │ ├── StyledTextPatcher.java │ ├── StyledTextRenderer.java │ └── internal │ │ └── StyledTextRendererEmulator.java │ └── provisional │ └── ILineSpacingProvider.java └── pom.xml /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | codelens-eclipse 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.m2e.core.maven2Builder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.m2e.core.maven2Nature 16 | 17 | 18 | -------------------------------------------------------------------------------- /.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding/=UTF-8 3 | -------------------------------------------------------------------------------- /.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: 4 | - oraclejdk8 5 | 6 | notifications: 7 | email: true 8 | -------------------------------------------------------------------------------- /CodeLensJDTDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/angelozerr/codelens-eclipse/186e3ff27a7ffa821ee641b8f49b826a38b0da77/CodeLensJDTDemo.gif -------------------------------------------------------------------------------- /CodeLensLSP4e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/angelozerr/codelens-eclipse/186e3ff27a7ffa821ee641b8f49b826a38b0da77/CodeLensLSP4e.png -------------------------------------------------------------------------------- /CodeLensStyledText.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/angelozerr/codelens-eclipse/186e3ff27a7ffa821ee641b8f49b826a38b0da77/CodeLensStyledText.gif -------------------------------------------------------------------------------- /CodeLensTypeScriptDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/angelozerr/codelens-eclipse/186e3ff27a7ffa821ee641b8f49b826a38b0da77/CodeLensTypeScriptDemo.gif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # codelens-eclipse 2 | 3 | [![Build Status](https://secure.travis-ci.org/angelozerr/codelens-eclipse.png)](http://travis-ci.org/angelozerr/codelens-eclipse) 4 | 5 | It exists today 2 bugs for implementing CodeLens inside Eclipse: bug [508458](https://bugs.eclipse.org/bugs/show_bug.cgi?id=508458) and [501546](https://bugs.eclipse.org/bugs/show_bug.cgi?id=501546). 6 | 7 | Today Javassist is required because there are 2 problems in Eclipse Platform: 8 | 9 | * bug with line numbers. See bug [481968](https://bugs.eclipse.org/bugs/show_bug.cgi?id=481968) 10 | * drawing CodeLens update line spacing of the line. Today StyledTExt doesn't provide this feature. See bug [522020](https://bugs.eclipse.org/bugs/show_bug.cgi?id=522020) 11 | 12 | This project is a POC to study how to implement CodeLens with Eclipse StyledText 13 | 14 | Here a demo with 15 | 16 | * `TypeScript` with [typescript.java](https://github.com/angelozerr/typescript.java) : 17 | 18 | ![CodeLens TypeScript Demo](CodeLensTypeScriptDemo.gif) 19 | 20 | * `Java` with `JDT Java Editor` : 21 | 22 | ![CodeLens JDT Demo](CodeLensJDTDemo.gif) 23 | 24 | * `Java` with [lsp4e Java Editor](https://github.com/eclipselabs/language-servers-for-eclipse/tree/master/org.eclipse.lsp4e.java) which uses Java Language Server of JDT : 25 | 26 | ![CodeLens lsp4e Demo](CodeLensLSP4e.png) 27 | 28 | Here a demo with the current work with StyledText where zone are added: 29 | 30 | ![CodeLens StyledText demo](CodeLensStyledText.gif) 31 | -------------------------------------------------------------------------------- /javassist/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /javassist/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /target/ -------------------------------------------------------------------------------- /javassist/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | javassist 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.pde.ManifestBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.pde.SchemaBuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.m2e.core.maven2Builder 25 | 26 | 27 | 28 | 29 | 30 | org.eclipse.m2e.core.maven2Nature 31 | org.eclipse.pde.PluginNature 32 | org.eclipse.jdt.core.javanature 33 | 34 | 35 | -------------------------------------------------------------------------------- /javassist/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding/=UTF-8 3 | -------------------------------------------------------------------------------- /javassist/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /javassist/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /javassist/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Name: Javassist 4 | Bundle-SymbolicName: javassist 5 | Bundle-Version: 1.3.0.qualifier 6 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 7 | Bundle-ClassPath: lib/javassist-3.11.jar, 8 | . 9 | Export-Package: javassist, 10 | javassist.bytecode, 11 | javassist.bytecode.analysis, 12 | javassist.bytecode.annotation, 13 | javassist.bytecode.stackmap, 14 | javassist.compiler, 15 | javassist.compiler.ast, 16 | javassist.convert, 17 | javassist.expr, 18 | javassist.runtime, 19 | javassist.scopedpool, 20 | javassist.tools, 21 | javassist.tools.reflect, 22 | javassist.tools.rmi, 23 | javassist.tools.web, 24 | javassist.util, 25 | javassist.util.proxy 26 | -------------------------------------------------------------------------------- /javassist/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/ 2 | output.. = bin/ 3 | bin.includes = META-INF/,\ 4 | .,\ 5 | lib/javassist-3.11.jar 6 | -------------------------------------------------------------------------------- /javassist/lib/javassist-3.11.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/angelozerr/codelens-eclipse/186e3ff27a7ffa821ee641b8f49b826a38b0da77/javassist/lib/javassist-3.11.jar -------------------------------------------------------------------------------- /javassist/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | javassist 4 | eclipse-plugin 5 | 6 | fr.opensagres.js 7 | codelens 8 | 1.1.0-SNAPSHOT 9 | 10 | 11 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /target/ -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.eclipse.codelens.editors 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.pde.ManifestBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.pde.SchemaBuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.m2e.core.maven2Builder 25 | 26 | 27 | 28 | 29 | 30 | org.eclipse.m2e.core.maven2Nature 31 | org.eclipse.pde.PluginNature 32 | org.eclipse.jdt.core.javanature 33 | 34 | 35 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate 4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.compliance=1.8 7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 12 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 13 | org.eclipse.jdt.core.compiler.source=1.8 14 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Vendor: %providerName 4 | Bundle-SymbolicName: org.eclipse.codelens.editors;singleton:=true 5 | Bundle-Version: 1.1.0.qualifier 6 | Require-Bundle: org.eclipse.core.runtime, 7 | org.eclipse.jface.text, 8 | org.eclipse.jface, 9 | org.eclipse.codelens, 10 | org.eclipse.ui.ide, 11 | org.eclipse.ui.workbench, 12 | org.eclipse.ui.workbench.texteditor 13 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 14 | Import-Package: javassist, 15 | javassist.bytecode, 16 | javassist.bytecode.analysis, 17 | javassist.bytecode.annotation, 18 | javassist.bytecode.stackmap, 19 | javassist.compiler, 20 | javassist.compiler.ast, 21 | javassist.convert, 22 | javassist.expr, 23 | javassist.runtime, 24 | javassist.scopedpool, 25 | javassist.tools, 26 | javassist.tools.reflect, 27 | javassist.tools.rmi, 28 | javassist.tools.web, 29 | javassist.util, 30 | javassist.util.proxy, 31 | org.eclipse.swt, 32 | org.eclipse.swt.custom, 33 | org.eclipse.swt.events, 34 | org.eclipse.swt.graphics, 35 | org.eclipse.swt.widgets 36 | Bundle-ClassPath: . 37 | Bundle-Name: %pluginName 38 | Bundle-ActivationPolicy: lazy 39 | Bundle-Activator: org.eclipse.codelens.editors.internal.CodeLensEditorPlugin 40 | Export-Package: org.eclipse.codelens.editors 41 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/ 2 | output.. = bin/ 3 | bin.includes = .,\ 4 | plugin.xml,\ 5 | plugin.properties,\ 6 | META-INF/,\ 7 | schema/ 8 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/plugin.properties: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Copyright (c) 2015-2017 Angelo Zerr and others. 3 | # All rights reserved. This program and the accompanying materials 4 | # are made available under the terms of the Eclipse Public License v1.0 5 | # which accompanies this distribution, and is available at 6 | # http://www.eclipse.org/legal/epl-v10.html 7 | # 8 | # Contributors: 9 | # Angelo Zerr - Initial API and implementation 10 | ############################################################################### 11 | pluginName=Eclipse CodeLens - JDT 12 | providerName=Angelo ZERR 13 | 14 | # Extension 15 | CodeLensControllerFactories.extension.name=CodeLens Controller Factories -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | 16 | 17 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | org.eclipse.codelens.editors 4 | eclipse-plugin 5 | 6 | fr.opensagres.js 7 | codelens 8 | 1.1.0-SNAPSHOT 9 | 10 | 11 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/schema/codeLensControllerFactories.exsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Extension point to register CodeLens controller factories. 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | a fully-qualified name of the target extension point 27 | 28 | 29 | 30 | 31 | 32 | 33 | an optional id 34 | 35 | 36 | 37 | 38 | 39 | 40 | an optional name 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | This extension point allows developers to register CodeLens controller factory. 51 | 52 | 53 | 54 | 55 | 56 | 57 | CodeLens Controller factory class. 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 2.0 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | This plugin itself does not have any predefined builders. 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/src/org/eclipse/codelens/editors/AbstractCodeLensController.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.editors; 2 | 3 | import org.eclipse.jface.text.provisional.codelens.CodeLensStrategy; 4 | import org.eclipse.ui.texteditor.ITextEditor; 5 | 6 | public abstract class AbstractCodeLensController implements ICodeLensController { 7 | 8 | private final ITextEditor textEditor; 9 | private CodeLensStrategy strategy; 10 | 11 | public AbstractCodeLensController(ITextEditor textEditor) { 12 | this.textEditor = textEditor; 13 | strategy = new CodeLensStrategy(createContext(textEditor)); 14 | } 15 | 16 | public void addTarget(String target) { 17 | strategy.addTarget(target); 18 | } 19 | 20 | protected EditorCodeLensContext createContext(ITextEditor textEditor) { 21 | return new EditorCodeLensContext(textEditor); 22 | } 23 | 24 | protected CodeLensStrategy getStrategy() { 25 | return strategy; 26 | } 27 | 28 | protected ITextEditor getTextEditor() { 29 | return textEditor; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/src/org/eclipse/codelens/editors/DefaultCodeLensController.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.editors; 2 | 3 | import org.eclipse.core.runtime.IProgressMonitor; 4 | import org.eclipse.jface.text.ITextOperationTarget; 5 | import org.eclipse.jface.text.ITextViewer; 6 | import org.eclipse.jface.text.reconciler.MonoReconciler; 7 | import org.eclipse.ui.texteditor.ITextEditor; 8 | 9 | public class DefaultCodeLensController extends AbstractCodeLensController { 10 | 11 | private MonoReconciler reconciler; 12 | private ITextViewer textViewer; 13 | 14 | public DefaultCodeLensController(ITextEditor textEditor) { 15 | super(textEditor); 16 | reconciler = new MonoReconciler(super.getStrategy(), false); 17 | reconciler.setDelay(500); 18 | } 19 | 20 | @Override 21 | public void install() { 22 | 23 | } 24 | 25 | @Override 26 | public void uninstall() { 27 | reconciler.uninstall(); 28 | } 29 | 30 | @Override 31 | public void refresh() { 32 | if (textViewer == null) { 33 | this.textViewer = (ITextViewer) getTextEditor().getAdapter(ITextOperationTarget.class); 34 | reconciler.install(textViewer); 35 | } 36 | getStrategy().initialReconcile(); 37 | } 38 | 39 | @Override 40 | public void setProgressMonitor(IProgressMonitor monitor) { 41 | reconciler.setProgressMonitor(monitor); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/src/org/eclipse/codelens/editors/EditorCodeLensContext.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.editors; 2 | 3 | import org.eclipse.jface.text.ITextOperationTarget; 4 | import org.eclipse.jface.text.ITextViewer; 5 | import org.eclipse.ui.texteditor.ITextEditor; 6 | 7 | public class EditorCodeLensContext implements IEditorCodeLensContext { 8 | 9 | private final ITextEditor textEditor; 10 | 11 | public EditorCodeLensContext(ITextEditor textEditor) { 12 | this.textEditor = textEditor; 13 | } 14 | 15 | @Override 16 | public ITextEditor getTextEditor() { 17 | return textEditor; 18 | } 19 | 20 | @Override 21 | public ITextViewer getViewer() { 22 | return (ITextViewer) textEditor.getAdapter(ITextOperationTarget.class); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/src/org/eclipse/codelens/editors/ICodeLensController.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.editors; 2 | 3 | import org.eclipse.core.runtime.IProgressMonitor; 4 | 5 | public interface ICodeLensController { 6 | 7 | void install(); 8 | 9 | void uninstall(); 10 | 11 | void refresh(); 12 | 13 | void setProgressMonitor(IProgressMonitor monitor); 14 | } 15 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/src/org/eclipse/codelens/editors/ICodeLensControllerFactory.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.editors; 2 | 3 | import org.eclipse.ui.texteditor.ITextEditor; 4 | 5 | public interface ICodeLensControllerFactory { 6 | 7 | boolean isRelevant(ITextEditor textEditor); 8 | 9 | ICodeLensController create(ITextEditor textEditor); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/src/org/eclipse/codelens/editors/IEditorCodeLensContext.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.editors; 2 | 3 | import org.eclipse.jface.text.provisional.codelens.ICodeLensContext; 4 | import org.eclipse.ui.texteditor.ITextEditor; 5 | 6 | public interface IEditorCodeLensContext extends ICodeLensContext { 7 | 8 | ITextEditor getTextEditor(); 9 | } 10 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/src/org/eclipse/codelens/editors/internal/CodeLensControllerRegistry.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.editors.internal; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.eclipse.codelens.editors.ICodeLensController; 7 | import org.eclipse.codelens.editors.ICodeLensControllerFactory; 8 | import org.eclipse.core.runtime.IConfigurationElement; 9 | import org.eclipse.core.runtime.IExtensionDelta; 10 | import org.eclipse.core.runtime.IExtensionRegistry; 11 | import org.eclipse.core.runtime.IRegistryChangeEvent; 12 | import org.eclipse.core.runtime.IRegistryChangeListener; 13 | import org.eclipse.core.runtime.Platform; 14 | import org.eclipse.ui.texteditor.ITextEditor; 15 | 16 | public class CodeLensControllerRegistry implements IRegistryChangeListener { 17 | 18 | private static final CodeLensControllerRegistry INSTANCE = new CodeLensControllerRegistry(); 19 | private static final String EXTENSION_CODELENS_CONTROLLER_FACTORIES = "codeLensControllerFactories"; 20 | 21 | public static CodeLensControllerRegistry getInstance() { 22 | return INSTANCE; 23 | } 24 | 25 | private boolean loaded; 26 | private final List factories; 27 | 28 | public CodeLensControllerRegistry() { 29 | this.factories = new ArrayList<>(); 30 | this.loaded = false; 31 | } 32 | 33 | public ICodeLensController create(ITextEditor textEditor) { 34 | ICodeLensControllerFactory factory = getFactory(textEditor); 35 | if (factory != null) { 36 | return factory.create(textEditor); 37 | } 38 | return null; 39 | } 40 | 41 | public ICodeLensControllerFactory getFactory(ITextEditor textEditor) { 42 | loadFactoriesIfNeeded(); 43 | for (ICodeLensControllerFactory factory : factories) { 44 | if (factory.isRelevant(textEditor)) { 45 | return factory; 46 | } 47 | } 48 | return null; 49 | } 50 | 51 | @Override 52 | public void registryChanged(IRegistryChangeEvent event) { 53 | IExtensionDelta[] deltas = event.getExtensionDeltas(CodeLensEditorPlugin.PLUGIN_ID, 54 | EXTENSION_CODELENS_CONTROLLER_FACTORIES); 55 | if (deltas != null) { 56 | for (IExtensionDelta delta : deltas) 57 | handleCodeLensProvidersDelta(delta); 58 | } 59 | } 60 | 61 | private void loadFactoriesIfNeeded() { 62 | if (loaded) { 63 | return; 64 | } 65 | loadFactories(); 66 | } 67 | 68 | /** 69 | * Load the SourceMap language supports. 70 | */ 71 | private synchronized void loadFactories() { 72 | if (loaded) { 73 | return; 74 | } 75 | 76 | try { 77 | IExtensionRegistry registry = Platform.getExtensionRegistry(); 78 | if (registry == null) { 79 | return; 80 | } 81 | IConfigurationElement[] cf = registry.getConfigurationElementsFor(CodeLensEditorPlugin.PLUGIN_ID, 82 | EXTENSION_CODELENS_CONTROLLER_FACTORIES); 83 | loadCodeLensProvidersFromExtension(cf); 84 | } finally { 85 | loaded = true; 86 | } 87 | } 88 | 89 | /** 90 | * Add the SourceMap language supports. 91 | */ 92 | private synchronized void loadCodeLensProvidersFromExtension(IConfigurationElement[] cf) { 93 | for (IConfigurationElement ce : cf) { 94 | try { 95 | ICodeLensControllerFactory factory = (ICodeLensControllerFactory) ce.createExecutableExtension("class"); 96 | factories.add(factory); 97 | } catch (Throwable e) { 98 | CodeLensEditorPlugin.log(e); 99 | } 100 | } 101 | } 102 | 103 | protected void handleCodeLensProvidersDelta(IExtensionDelta delta) { 104 | if (!loaded) // not loaded yet 105 | return; 106 | 107 | IConfigurationElement[] cf = delta.getExtension().getConfigurationElements(); 108 | 109 | // List list = new 110 | // ArrayList( 111 | // codeLensProviders); 112 | // if (delta.getKind() == IExtensionDelta.ADDED) { 113 | // loadCodeLensProvidersFromExtension(cf, list); 114 | // } else { 115 | // int size = list.size(); 116 | // CodeLensProviderType[] st = new CodeLensProviderType[size]; 117 | // list.toArray(st); 118 | // int size2 = cf.length; 119 | // 120 | // for (int i = 0; i < size; i++) { 121 | // for (int j = 0; j < size2; j++) { 122 | // if (st[i].getId().equals(cf[j].getAttribute("id"))) { 123 | // list.remove(st[i]); 124 | // } 125 | // } 126 | // } 127 | // } 128 | // codeLensProviders = list; 129 | } 130 | 131 | public void initialize() { 132 | IExtensionRegistry registry = Platform.getExtensionRegistry(); 133 | registry.addRegistryChangeListener(this, CodeLensEditorPlugin.PLUGIN_ID); 134 | } 135 | 136 | public void destroy() { 137 | Platform.getExtensionRegistry().removeRegistryChangeListener(this); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/src/org/eclipse/codelens/editors/internal/CodeLensEditorPlugin.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-2016 Angelo ZERR. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * Angelo Zerr - initial API and implementation 10 | * Lorenzo Dalla Vecchia - getter for ProblemManager 11 | */ 12 | package org.eclipse.codelens.editors.internal; 13 | 14 | import org.eclipse.core.runtime.CoreException; 15 | import org.eclipse.core.runtime.IStatus; 16 | import org.eclipse.core.runtime.Status; 17 | import org.eclipse.ui.plugin.AbstractUIPlugin; 18 | import org.osgi.framework.BundleContext; 19 | 20 | /** 21 | * The activator class controls the plug-in life cycle 22 | */ 23 | public class CodeLensEditorPlugin extends AbstractUIPlugin { 24 | 25 | public static final String PLUGIN_ID = "org.eclipse.codelens.editors"; //$NON-NLS-1$ 26 | 27 | // The shared instance. 28 | private static CodeLensEditorPlugin plugin; 29 | 30 | /** 31 | * The constructor. 32 | */ 33 | public CodeLensEditorPlugin() { 34 | super(); 35 | plugin = this; 36 | } 37 | 38 | @Override 39 | public void start(BundleContext context) throws Exception { 40 | super.start(context); 41 | CodeLensControllerRegistry.getInstance().initialize(); 42 | } 43 | 44 | @Override 45 | public void stop(BundleContext context) throws Exception { 46 | CodeLensControllerRegistry.getInstance().initialize(); 47 | plugin = null; 48 | super.stop(context); 49 | } 50 | 51 | /** 52 | * Returns the shared instance 53 | * 54 | * @return the shared instance 55 | */ 56 | public static CodeLensEditorPlugin getDefault() { 57 | return plugin; 58 | } 59 | 60 | public static void log(IStatus status) { 61 | CodeLensEditorPlugin plugin = getDefault(); 62 | if (plugin != null) { 63 | plugin.getLog().log(status); 64 | } else { 65 | System.err.println(status.getPlugin() + ": " + status.getMessage()); //$NON-NLS-1$ 66 | } 67 | } 68 | 69 | public static void log(Throwable e) { 70 | if (e instanceof CoreException) { 71 | log(new Status(IStatus.ERROR, PLUGIN_ID, ((CoreException) e).getStatus().getSeverity(), e.getMessage(), 72 | e.getCause())); 73 | } else { 74 | log(new Status(IStatus.ERROR, PLUGIN_ID, e.getMessage(), e)); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/src/org/eclipse/codelens/editors/internal/CodeLensEditorStartup.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-2016 Angelo ZERR. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * Angelo Zerr - initial API and implementation 10 | */ 11 | package org.eclipse.codelens.editors.internal; 12 | 13 | import org.eclipse.ui.IStartup; 14 | import org.eclipse.ui.IWorkbench; 15 | import org.eclipse.ui.IWorkbenchWindow; 16 | import org.eclipse.ui.PlatformUI; 17 | 18 | public class CodeLensEditorStartup implements IStartup { 19 | 20 | @Override 21 | public void earlyStartup() { 22 | final IWorkbench workbench = PlatformUI.getWorkbench(); 23 | workbench.getDisplay().asyncExec(new Runnable() { 24 | public void run() { 25 | // Editor tracker 26 | IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); 27 | if (window != null) { 28 | EditorTracker.getInstance(); 29 | } 30 | } 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /org.eclipse.codelens.editors/src/org/eclipse/codelens/editors/internal/EditorTracker.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.editors.internal; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.eclipse.codelens.editors.ICodeLensController; 7 | import org.eclipse.core.runtime.Assert; 8 | import org.eclipse.core.runtime.NullProgressMonitor; 9 | import org.eclipse.jface.text.ITextOperationTarget; 10 | import org.eclipse.jface.text.ITextViewer; 11 | import org.eclipse.ui.IEditorPart; 12 | import org.eclipse.ui.IEditorReference; 13 | import org.eclipse.ui.IPageListener; 14 | import org.eclipse.ui.IPartListener; 15 | import org.eclipse.ui.IWindowListener; 16 | import org.eclipse.ui.IWorkbench; 17 | import org.eclipse.ui.IWorkbenchPage; 18 | import org.eclipse.ui.IWorkbenchPart; 19 | import org.eclipse.ui.IWorkbenchWindow; 20 | import org.eclipse.ui.PlatformUI; 21 | import org.eclipse.ui.texteditor.ITextEditor; 22 | 23 | public class EditorTracker implements IWindowListener, IPageListener, IPartListener { 24 | 25 | private static EditorTracker INSTANCE; 26 | 27 | private Map codeLensControllers = new HashMap<>(); 28 | 29 | private EditorTracker() { 30 | init(); 31 | } 32 | 33 | public static EditorTracker getInstance() { 34 | if (INSTANCE == null) { 35 | INSTANCE = new EditorTracker(); 36 | } 37 | return INSTANCE; 38 | } 39 | 40 | private void init() { 41 | if (PlatformUI.isWorkbenchRunning()) { 42 | IWorkbench workbench = CodeLensEditorPlugin.getDefault().getWorkbench(); 43 | if (workbench != null) { 44 | IWorkbenchWindow[] windows = workbench.getWorkbenchWindows(); 45 | for (IWorkbenchWindow window : windows) { 46 | windowOpened(window); 47 | } 48 | CodeLensEditorPlugin.getDefault().getWorkbench().addWindowListener(this); 49 | } 50 | } 51 | } 52 | 53 | @Override 54 | public void windowActivated(IWorkbenchWindow window) { 55 | } 56 | 57 | @Override 58 | public void windowDeactivated(IWorkbenchWindow window) { 59 | } 60 | 61 | @Override 62 | public void windowClosed(IWorkbenchWindow window) { 63 | IWorkbenchPage[] pages = window.getPages(); 64 | for (IWorkbenchPage page : pages) { 65 | pageClosed(page); 66 | } 67 | window.removePageListener(this); 68 | } 69 | 70 | @Override 71 | public void windowOpened(IWorkbenchWindow window) { 72 | if (window.getShell() != null) { 73 | IWorkbenchPage[] pages = window.getPages(); 74 | for (IWorkbenchPage page : pages) { 75 | pageOpened(page); 76 | } 77 | window.addPageListener(this); 78 | } 79 | } 80 | 81 | @Override 82 | public void pageActivated(IWorkbenchPage page) { 83 | } 84 | 85 | @Override 86 | public void pageClosed(IWorkbenchPage page) { 87 | IEditorReference[] rs = page.getEditorReferences(); 88 | for (IEditorReference r : rs) { 89 | IEditorPart part = r.getEditor(false); 90 | if (part != null) { 91 | editorClosed(part); 92 | } 93 | } 94 | page.removePartListener(this); 95 | } 96 | 97 | @Override 98 | public void pageOpened(IWorkbenchPage page) { 99 | IEditorReference[] rs = page.getEditorReferences(); 100 | for (IEditorReference r : rs) { 101 | IEditorPart part = r.getEditor(false); 102 | if (part != null) { 103 | editorOpened(part); 104 | } 105 | } 106 | page.addPartListener(this); 107 | } 108 | 109 | @Override 110 | public void partActivated(IWorkbenchPart part) { 111 | if (part instanceof ITextEditor) { 112 | ITextViewer textViewer = (ITextViewer) part.getAdapter(ITextOperationTarget.class); 113 | if (textViewer != null) { 114 | ICodeLensController controller = codeLensControllers.get(part); 115 | if (controller != null) { 116 | controller.refresh(); 117 | } 118 | } 119 | } 120 | } 121 | 122 | @Override 123 | public void partBroughtToTop(IWorkbenchPart part) { 124 | } 125 | 126 | @Override 127 | public void partClosed(IWorkbenchPart part) { 128 | if (part instanceof IEditorPart) { 129 | editorClosed((IEditorPart) part); 130 | } 131 | } 132 | 133 | @Override 134 | public void partDeactivated(IWorkbenchPart part) { 135 | } 136 | 137 | @Override 138 | public void partOpened(IWorkbenchPart part) { 139 | if (part instanceof IEditorPart) { 140 | editorOpened((IEditorPart) part); 141 | } 142 | } 143 | 144 | private void editorOpened(IEditorPart part) { 145 | if (part instanceof ITextEditor) { 146 | ITextViewer textViewer = (ITextViewer) part.getAdapter(ITextOperationTarget.class); 147 | if (textViewer != null) { 148 | ICodeLensController controller = codeLensControllers.get(part); 149 | if (controller == null) { 150 | ITextEditor textEditor = (ITextEditor) part; 151 | controller = CodeLensControllerRegistry.getInstance().create(textEditor); 152 | if (controller != null) { 153 | controller.setProgressMonitor(new NullProgressMonitor()); 154 | codeLensControllers.put(textEditor, controller); 155 | //controller.install(); 156 | } 157 | } 158 | } 159 | } 160 | } 161 | 162 | private void editorClosed(IEditorPart part) { 163 | if (part instanceof ITextEditor) { 164 | ICodeLensController controller = codeLensControllers.remove(part); 165 | if (controller != null) { 166 | controller.uninstall(); 167 | Assert.isTrue(null == codeLensControllers.get(part), 168 | "An old ICodeLensController is not un-installed on Text Editor instance"); 169 | } 170 | } 171 | } 172 | 173 | } 174 | -------------------------------------------------------------------------------- /org.eclipse.codelens.feature/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /org.eclipse.codelens.feature/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.eclipse.codelens.feature 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.pde.FeatureBuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.m2e.core.maven2Nature 21 | org.eclipse.pde.FeatureNature 22 | 23 | 24 | -------------------------------------------------------------------------------- /org.eclipse.codelens.feature/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /org.eclipse.codelens.feature/build.properties: -------------------------------------------------------------------------------- 1 | bin.includes = epl-v10.html,\ 2 | feature.properties,\ 3 | feature.xml,\ 4 | license.html 5 | -------------------------------------------------------------------------------- /org.eclipse.codelens.feature/feature.properties: -------------------------------------------------------------------------------- 1 | # "featureName" property - name of the feature 2 | featureName = CodeLens for Eclipse 3 | featureProvider = Angelo ZERR 4 | 5 | # "description" property - description of the feature 6 | description = CodeLens support in Eclipse IDE 7 | 8 | # "copyright" property - copyright of the feature 9 | copyright = Copyright (c) 2015 - 2017 Angelo ZERR and others. All rights reserved. 10 | 11 | # "licenseURL" property - URL of the "Feature License" 12 | # do not translate value - just change to point to a locale-specific HTML page 13 | licenseURL = license.html 14 | 15 | # "license" property - text of the "Feature Update License" 16 | # should be plain text version of license agreement pointed to be "licenseURL" 17 | license=\ 18 | Eclipse Foundation Software User Agreement\n\ 19 | April 14, 2010\n\ 20 | \n\ 21 | Usage Of Content\n\ 22 | \n\ 23 | THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\ 24 | OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\ 25 | USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\ 26 | AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\ 27 | NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\ 28 | AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\ 29 | AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\ 30 | OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ 31 | TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\ 32 | OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ 33 | BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\ 34 | \n\ 35 | Applicable Licenses\n\ 36 | \n\ 37 | Unless otherwise indicated, all Content made available by the\n\ 38 | Eclipse Foundation is provided to you under the terms and conditions of\n\ 39 | the Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is\n\ 40 | provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\ 41 | For purposes of the EPL, "Program" will mean the Content.\n\ 42 | \n\ 43 | Content includes, but is not limited to, source code, object code,\n\ 44 | documentation and other files maintained in the Eclipse Foundation source code\n\ 45 | repository ("Repository") in software modules ("Modules") and made available\n\ 46 | as downloadable archives ("Downloads").\n\ 47 | \n\ 48 | - Content may be structured and packaged into modules to facilitate delivering,\n\ 49 | extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\ 50 | plug-in fragments ("Fragments"), and features ("Features").\n\ 51 | - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java(TM) ARchive)\n\ 52 | in a directory named "plugins".\n\ 53 | - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\ 54 | Each Feature may be packaged as a sub-directory in a directory named "features".\n\ 55 | Within a Feature, files named "feature.xml" may contain a list of the names and version\n\ 56 | numbers of the Plug-ins and/or Fragments associated with that Feature.\n\ 57 | - Features may also include other Features ("Included Features"). Within a Feature, files\n\ 58 | named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\ 59 | \n\ 60 | The terms and conditions governing Plug-ins and Fragments should be\n\ 61 | contained in files named "about.html" ("Abouts"). The terms and\n\ 62 | conditions governing Features and Included Features should be contained\n\ 63 | in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\ 64 | Licenses may be located in any directory of a Download or Module\n\ 65 | including, but not limited to the following locations:\n\ 66 | \n\ 67 | - The top-level (root) directory\n\ 68 | - Plug-in and Fragment directories\n\ 69 | - Inside Plug-ins and Fragments packaged as JARs\n\ 70 | - Sub-directories of the directory named "src" of certain Plug-ins\n\ 71 | - Feature directories\n\ 72 | \n\ 73 | Note: if a Feature made available by the Eclipse Foundation is installed using the\n\ 74 | Provisioning Technology (as defined below), you must agree to a license ("Feature \n\ 75 | Update License") during the installation process. If the Feature contains\n\ 76 | Included Features, the Feature Update License should either provide you\n\ 77 | with the terms and conditions governing the Included Features or inform\n\ 78 | you where you can locate them. Feature Update Licenses may be found in\n\ 79 | the "license" property of files named "feature.properties" found within a Feature.\n\ 80 | Such Abouts, Feature Licenses, and Feature Update Licenses contain the\n\ 81 | terms and conditions (or references to such terms and conditions) that\n\ 82 | govern your use of the associated Content in that directory.\n\ 83 | \n\ 84 | THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER\n\ 85 | TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\ 86 | SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ 87 | \n\ 88 | - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\ 89 | - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\ 90 | - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\ 91 | - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\ 92 | - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\ 93 | \n\ 94 | IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\ 95 | TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License\n\ 96 | is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\ 97 | govern that particular Content.\n\ 98 | \n\ 99 | \n\Use of Provisioning Technology\n\ 100 | \n\ 101 | The Eclipse Foundation makes available provisioning software, examples of which include,\n\ 102 | but are not limited to, p2 and the Eclipse Update Manager ("Provisioning Technology") for\n\ 103 | the purpose of allowing users to install software, documentation, information and/or\n\ 104 | other materials (collectively "Installable Software"). This capability is provided with\n\ 105 | the intent of allowing such users to install, extend and update Eclipse-based products.\n\ 106 | Information about packaging Installable Software is available at\n\ 107 | http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ 108 | \n\ 109 | You may use Provisioning Technology to allow other parties to install Installable Software.\n\ 110 | You shall be responsible for enabling the applicable license agreements relating to the\n\ 111 | Installable Software to be presented to, and accepted by, the users of the Provisioning Technology\n\ 112 | in accordance with the Specification. By using Provisioning Technology in such a manner and\n\ 113 | making it available in accordance with the Specification, you further acknowledge your\n\ 114 | agreement to, and the acquisition of all necessary rights to permit the following:\n\ 115 | \n\ 116 | 1. A series of actions may occur ("Provisioning Process") in which a user may execute\n\ 117 | the Provisioning Technology on a machine ("Target Machine") with the intent of installing,\n\ 118 | extending or updating the functionality of an Eclipse-based product.\n\ 119 | 2. During the Provisioning Process, the Provisioning Technology may cause third party\n\ 120 | Installable Software or a portion thereof to be accessed and copied to the Target Machine.\n\ 121 | 3. Pursuant to the Specification, you will provide to the user the terms and conditions that\n\ 122 | govern the use of the Installable Software ("Installable Software Agreement") and such\n\ 123 | Installable Software Agreement shall be accessed from the Target Machine in accordance\n\ 124 | with the Specification. Such Installable Software Agreement must inform the user of the\n\ 125 | terms and conditions that govern the Installable Software and must solicit acceptance by\n\ 126 | the end user in the manner prescribed in such Installable Software Agreement. Upon such\n\ 127 | indication of agreement by the user, the provisioning Technology will complete installation\n\ 128 | of the Installable Software.\n\ 129 | \n\ 130 | Cryptography\n\ 131 | \n\ 132 | Content may contain encryption software. The country in which you are\n\ 133 | currently may have restrictions on the import, possession, and use,\n\ 134 | and/or re-export to another country, of encryption software. BEFORE\n\ 135 | using any encryption software, please check the country's laws,\n\ 136 | regulations and policies concerning the import, possession, or use, and\n\ 137 | re-export of encryption software, to see if this is permitted.\n\ 138 | \n\ 139 | Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.\n 140 | ########### end of license property ########################################## 141 | -------------------------------------------------------------------------------- /org.eclipse.codelens.feature/feature.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | %description 12 | 13 | 14 | 15 | %copyright 16 | 17 | 18 | 19 | %license 20 | 21 | 22 | 28 | 29 | 35 | 36 | 43 | 44 | 51 | 52 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /org.eclipse.codelens.feature/license.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Eclipse Foundation Software User Agreement 8 | 9 |

Eclipse Foundation Software User Agreement

10 |

February 1, 2011

11 | 12 |

Usage Of Content

13 | 14 |

THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS 15 | (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND 16 | CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE 17 | OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR 18 | NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND 19 | CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.

20 | 21 |

Applicable Licenses

22 | 23 |

Unless otherwise indicated, all Content made available by the Eclipse 24 | Foundation is provided to you under the terms and conditions of the 25 | Eclipse Public License Version 1.0 26 | ("EPL"). A copy of the EPL is provided with this Content and is also 27 | available at http://www.eclipse.org/legal/epl-v10.html. 28 | For purposes of the EPL, "Program" will mean the Content.

29 | 30 |

Content includes, but is not limited to, source code, object code, 31 | documentation and other files maintained in the Eclipse Foundation 32 | source code 33 | repository ("Repository") in software modules ("Modules") and made 34 | available as downloadable archives ("Downloads").

35 | 36 |
    37 |
  • Content may be structured and packaged into modules to 38 | facilitate delivering, extending, and upgrading the Content. Typical 39 | modules may include plug-ins ("Plug-ins"), plug-in fragments 40 | ("Fragments"), and features ("Features").
  • 41 |
  • Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".
  • 42 |
  • A Feature is a bundle of one or more Plug-ins and/or 43 | Fragments and associated material. Each Feature may be packaged as a 44 | sub-directory in a directory named "features". Within a Feature, files 45 | named "feature.xml" may contain a list of the names and version numbers 46 | of the Plug-ins 47 | and/or Fragments associated with that Feature.
  • 48 |
  • Features may also include other Features ("Included 49 | Features"). Within a Feature, files named "feature.xml" may contain a 50 | list of the names and version numbers of Included Features.
  • 51 |
52 | 53 |

The terms and conditions governing Plug-ins and Fragments should be 54 | contained in files named "about.html" ("Abouts"). The terms and 55 | conditions governing Features and 56 | Included Features should be contained in files named "license.html" 57 | ("Feature Licenses"). Abouts and Feature Licenses may be located in any 58 | directory of a Download or Module 59 | including, but not limited to the following locations:

60 | 61 |
    62 |
  • The top-level (root) directory
  • 63 |
  • Plug-in and Fragment directories
  • 64 |
  • Inside Plug-ins and Fragments packaged as JARs
  • 65 |
  • Sub-directories of the directory named "src" of certain Plug-ins
  • 66 |
  • Feature directories
  • 67 |
68 | 69 |

Note: if a Feature made available by the Eclipse Foundation is 70 | installed using the Provisioning Technology (as defined below), you must 71 | agree to a license ("Feature Update License") during the 72 | installation process. If the Feature contains Included Features, the 73 | Feature Update License should either provide you with the terms and 74 | conditions governing the Included Features or 75 | inform you where you can locate them. Feature Update Licenses may be 76 | found in the "license" property of files named "feature.properties" 77 | found within a Feature. 78 | Such Abouts, Feature Licenses, and Feature Update Licenses contain the 79 | terms and conditions (or references to such terms and conditions) that 80 | govern your use of the associated Content in 81 | that directory.

82 | 83 |

THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER 84 | TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. 85 | SOME OF THESE 86 | OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):

87 | 88 | 96 | 97 |

IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND 98 | CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, 99 | or Feature Update License is provided, please 100 | contact the Eclipse Foundation to determine what terms and conditions 101 | govern that particular Content.

102 | 103 | 104 |

Use of Provisioning Technology

105 | 106 |

The Eclipse Foundation makes available provisioning software, 107 | examples of which include, but are not limited to, p2 and the Eclipse 108 | Update Manager ("Provisioning Technology") for the purpose of 109 | allowing users to install software, documentation, information and/or 110 | other materials (collectively "Installable Software"). This 111 | capability is provided with the intent of allowing such users to 112 | install, extend and update Eclipse-based products. Information about 113 | packaging Installable Software is available at http://eclipse.org/equinox/p2/repository_packaging.html 114 | ("Specification").

115 | 116 |

You may use Provisioning Technology to allow other parties to install 117 | Installable Software. You shall be responsible for enabling the 118 | applicable license agreements relating to the Installable Software to 119 | be presented to, and accepted by, the users of the Provisioning 120 | Technology 121 | in accordance with the Specification. By using Provisioning 122 | Technology in such a manner and making it available in accordance with 123 | the 124 | Specification, you further acknowledge your agreement to, and the 125 | acquisition of all necessary rights to permit the following:

126 | 127 |
    128 |
  1. A series of actions may occur ("Provisioning Process") in 129 | which a user may execute the Provisioning Technology 130 | on a machine ("Target Machine") with the intent of installing, 131 | extending or updating the functionality of an Eclipse-based 132 | product.
  2. 133 |
  3. During the Provisioning Process, the Provisioning Technology 134 | may cause third party Installable Software or a portion thereof to be 135 | accessed and copied to the Target Machine.
  4. 136 |
  5. Pursuant to the Specification, you will provide to the user 137 | the terms and conditions that govern the use of the Installable 138 | Software ("Installable Software Agreement") and such Installable 139 | Software Agreement shall be accessed from the Target 140 | Machine in accordance with the Specification. Such Installable 141 | Software Agreement must inform the user of the terms and conditions that 142 | govern 143 | the Installable Software and must solicit acceptance by the end 144 | user in the manner prescribed in such Installable Software Agreement. 145 | Upon such 146 | indication of agreement by the user, the provisioning Technology 147 | will complete installation of the Installable Software.
  6. 148 |
149 | 150 |

Cryptography

151 | 152 |

Content may contain encryption software. The country in which you are 153 | currently may have restrictions on the import, possession, and use, 154 | and/or re-export to 155 | another country, of encryption software. BEFORE using any encryption 156 | software, please check the country's laws, regulations and policies 157 | concerning the import, 158 | possession, or use, and re-export of encryption software, to see if 159 | this is permitted.

160 | 161 |

Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.

162 | 163 | -------------------------------------------------------------------------------- /org.eclipse.codelens.feature/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | fr.opensagres.js 6 | codelens 7 | 1.1.0-SNAPSHOT 8 | 9 | org.eclipse.codelens.feature 10 | eclipse-feature 11 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jdt/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jdt/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /target/ -------------------------------------------------------------------------------- /org.eclipse.codelens.jdt/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.eclipse.codelens.jdt 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.pde.ManifestBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.pde.SchemaBuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.m2e.core.maven2Builder 25 | 26 | 27 | 28 | 29 | 30 | org.eclipse.m2e.core.maven2Nature 31 | org.eclipse.pde.PluginNature 32 | org.eclipse.jdt.core.javanature 33 | 34 | 35 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jdt/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate 4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.compliance=1.8 7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 12 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 13 | org.eclipse.jdt.core.compiler.source=1.8 14 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jdt/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jdt/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Vendor: %providerName 4 | Bundle-SymbolicName: org.eclipse.codelens.jdt;singleton:=true 5 | Bundle-Version: 1.1.0.qualifier 6 | Require-Bundle: org.eclipse.core.runtime, 7 | org.eclipse.jface.text, 8 | org.eclipse.jface, 9 | org.eclipse.jdt.core, 10 | org.eclipse.codelens, 11 | org.eclipse.ui.ide, 12 | org.eclipse.ui.workbench, 13 | org.eclipse.ui.workbench.texteditor, 14 | org.eclipse.codelens.editors, 15 | org.eclipse.jdt.ui, 16 | org.eclipse.core.resources, 17 | org.eclipse.jdt.junit.core 18 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 19 | Import-Package: javassist, 20 | javassist.bytecode, 21 | javassist.bytecode.analysis, 22 | javassist.bytecode.annotation, 23 | javassist.bytecode.stackmap, 24 | javassist.compiler, 25 | javassist.compiler.ast, 26 | javassist.convert, 27 | javassist.expr, 28 | javassist.runtime, 29 | javassist.scopedpool, 30 | javassist.tools, 31 | javassist.tools.reflect, 32 | javassist.tools.rmi, 33 | javassist.tools.web, 34 | javassist.util, 35 | javassist.util.proxy, 36 | org.eclipse.swt, 37 | org.eclipse.swt.custom, 38 | org.eclipse.swt.events, 39 | org.eclipse.swt.graphics, 40 | org.eclipse.swt.widgets 41 | Bundle-ClassPath: . 42 | Bundle-Name: %pluginName 43 | Bundle-ActivationPolicy: lazy 44 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jdt/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/ 2 | output.. = bin/ 3 | bin.includes = .,\ 4 | plugin.xml,\ 5 | plugin.properties,\ 6 | META-INF/ 7 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jdt/plugin.properties: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Copyright (c) 2015-2017 Angelo Zerr and others. 3 | # All rights reserved. This program and the accompanying materials 4 | # are made available under the terms of the Eclipse Public License v1.0 5 | # which accompanies this distribution, and is available at 6 | # http://www.eclipse.org/legal/epl-v10.html 7 | # 8 | # Contributors: 9 | # Angelo Zerr - Initial API and implementation 10 | ############################################################################### 11 | pluginName=Eclipse CodeLens - JDT 12 | providerName=Angelo ZERR 13 | 14 | JavaCodeLensProvider.name=Java References/Implementation CodeLens -------------------------------------------------------------------------------- /org.eclipse.codelens.jdt/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | 16 | 17 | 19 | 21 | 22 | 23 | 24 | 26 | 27 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jdt/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | org.eclipse.codelens.jdt 4 | eclipse-plugin 5 | 6 | fr.opensagres.js 7 | codelens 8 | 1.1.0-SNAPSHOT 9 | 10 | 11 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jdt/src/org/eclipse/codelens/jdt/internal/JDTUtils.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.jdt.internal; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | import java.util.Set; 7 | 8 | import org.eclipse.core.runtime.CoreException; 9 | import org.eclipse.jdt.core.IAnnotatable; 10 | import org.eclipse.jdt.core.IAnnotation; 11 | import org.eclipse.jdt.core.IBuffer; 12 | import org.eclipse.jdt.core.IClassFile; 13 | import org.eclipse.jdt.core.IJavaElement; 14 | import org.eclipse.jdt.core.IJavaProject; 15 | import org.eclipse.jdt.core.IMemberValuePair; 16 | import org.eclipse.jdt.core.IOpenable; 17 | import org.eclipse.jdt.core.ITypeRoot; 18 | import org.eclipse.jdt.core.JavaModelException; 19 | import org.eclipse.jdt.core.ToolFactory; 20 | import org.eclipse.jdt.core.search.IJavaSearchConstants; 21 | import org.eclipse.jdt.core.search.IJavaSearchScope; 22 | import org.eclipse.jdt.core.search.SearchEngine; 23 | import org.eclipse.jdt.core.search.SearchMatch; 24 | import org.eclipse.jdt.core.search.SearchParticipant; 25 | import org.eclipse.jdt.core.search.SearchPattern; 26 | import org.eclipse.jdt.core.search.SearchRequestor; 27 | import org.eclipse.jdt.core.util.ClassFileBytesDisassembler; 28 | import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; 29 | import org.eclipse.jface.text.BadLocationException; 30 | import org.eclipse.jface.text.Document; 31 | import org.eclipse.jface.text.IDocument; 32 | import org.eclipse.jface.text.provisional.codelens.Range; 33 | import org.eclipse.ui.texteditor.ITextEditor; 34 | 35 | public class JDTUtils { 36 | 37 | private static Set SILENCED_CODEGENS = Collections.singleton("lombok"); 38 | public static final String MISSING_SOURCES_HEADER = " // Failed to get sources. Instead, stub sources have been generated.\n" 39 | + " // Implementation of methods is unavailable.\n"; 40 | private static final String LF = "\n"; 41 | 42 | public static ITypeRoot resolveCompilationUnit(ITextEditor textEditor) { 43 | return EditorUtility.getEditorInputJavaElement(textEditor, true); 44 | } 45 | 46 | public static boolean isHiddenGeneratedElement(IJavaElement element) { 47 | // generated elements are tagged with javax.annotation.Generated and 48 | // they need to be filtered out 49 | if (element instanceof IAnnotatable) { 50 | try { 51 | IAnnotation[] annotations = ((IAnnotatable) element).getAnnotations(); 52 | if (annotations.length != 0) { 53 | for (IAnnotation annotation : annotations) { 54 | if (isSilencedGeneratedAnnotation(annotation)) { 55 | return true; 56 | } 57 | } 58 | } 59 | } catch (JavaModelException e) { 60 | // ignore 61 | } 62 | } 63 | return false; 64 | } 65 | 66 | private static boolean isSilencedGeneratedAnnotation(IAnnotation annotation) throws JavaModelException { 67 | if ("javax.annotation.Generated".equals(annotation.getElementName())) { 68 | IMemberValuePair[] memberValuePairs = annotation.getMemberValuePairs(); 69 | for (IMemberValuePair m : memberValuePairs) { 70 | if ("value".equals(m.getMemberName()) && IMemberValuePair.K_STRING == m.getValueKind()) { 71 | if (m.getValue() instanceof String) { 72 | return SILENCED_CODEGENS.contains(m.getValue()); 73 | } else if (m.getValue() instanceof Object[]) { 74 | for (Object val : (Object[]) m.getValue()) { 75 | if (SILENCED_CODEGENS.contains(val)) { 76 | return true; 77 | } 78 | } 79 | } 80 | } 81 | } 82 | } 83 | return false; 84 | } 85 | 86 | public static Range toRange(IOpenable openable, int offset, int length) throws JavaModelException { 87 | if (offset > 0 || length > 0) { 88 | int[] loc = null; 89 | int[] endLoc = null; 90 | IBuffer buffer = openable.getBuffer(); 91 | // if (buffer != null) { 92 | // loc = JsonRpcHelpers.toLine(buffer, offset); 93 | // endLoc = JsonRpcHelpers.toLine(buffer, offset + length); 94 | // } 95 | // if (loc == null) { 96 | // loc = new int[2]; 97 | // } 98 | // if (endLoc == null) { 99 | // endLoc = new int[2]; 100 | // } 101 | // setPosition(range.getStart(), loc); 102 | // setPosition(range.getEnd(), endLoc); 103 | IDocument document = toDocument(buffer); 104 | try { 105 | int line = document.getLineOfOffset(offset); 106 | int column = offset - document.getLineOffset(line); 107 | return new Range(line + 1, column + 1); 108 | } catch (BadLocationException e) { 109 | // TODO Auto-generated catch block 110 | e.printStackTrace(); 111 | } 112 | } 113 | // TODO Auto-generated method stub 114 | return null; 115 | } 116 | 117 | /** 118 | * Returns an {@link IDocument} for the given buffer. The implementation tries 119 | * to avoid copying the buffer unless required. The returned document may or may 120 | * not be connected to the buffer. 121 | * 122 | * @param buffer 123 | * a buffer 124 | * @return a document with the same contents as the buffer or null 125 | * is the buffer is null 126 | */ 127 | public static IDocument toDocument(IBuffer buffer) { 128 | if (buffer == null) { 129 | return null; 130 | } 131 | if (buffer instanceof IDocument) { 132 | return (IDocument) buffer; 133 | } else if (buffer instanceof org.eclipse.jdt.internal.ui.javaeditor.DocumentAdapter) { 134 | IDocument document = ((org.eclipse.jdt.internal.ui.javaeditor.DocumentAdapter) buffer).getDocument(); 135 | if (document != null) { 136 | return document; 137 | } 138 | } 139 | return new org.eclipse.jdt.internal.core.DocumentAdapter(buffer); 140 | } 141 | 142 | public static IJavaElement findElementAtSelection(ITypeRoot unit, Range range) 143 | throws JavaModelException, BadLocationException { 144 | return findElementAtSelection(unit, range.startLineNumber - 1, range.startColumn - 1); 145 | } 146 | 147 | public static IJavaElement findElementAtSelection(ITypeRoot unit, int line, int column) 148 | throws JavaModelException, BadLocationException { 149 | IJavaElement[] elements = findElementsAtSelection(unit, line, column); 150 | if (elements != null && elements.length == 1) { 151 | return elements[0]; 152 | } 153 | return null; 154 | } 155 | 156 | public static IJavaElement[] findElementsAtSelection(ITypeRoot unit, int line, int column) 157 | throws JavaModelException, BadLocationException { 158 | if (unit == null) { 159 | return null; 160 | } 161 | int offset = toDocument(unit.getBuffer()).getLineOffset(line) + column; 162 | if (offset > -1) { 163 | return unit.codeSelect(offset, 0); 164 | } 165 | if (unit instanceof IClassFile) { 166 | IClassFile classFile = (IClassFile) unit; 167 | String contents = disassemble(classFile); 168 | if (contents != null) { 169 | IDocument document = new Document(contents); 170 | try { 171 | offset = document.getLineOffset(line) + column; 172 | if (offset > -1) { 173 | String name = parse(contents, offset); 174 | if (name == null) { 175 | return null; 176 | } 177 | SearchPattern pattern = SearchPattern.createPattern(name, IJavaSearchConstants.TYPE, 178 | IJavaSearchConstants.DECLARATIONS, SearchPattern.R_FULL_MATCH); 179 | 180 | IJavaSearchScope scope = createSearchScope(unit.getJavaProject()); 181 | 182 | List elements = new ArrayList<>(); 183 | SearchRequestor requestor = new SearchRequestor() { 184 | @Override 185 | public void acceptSearchMatch(SearchMatch match) { 186 | if (match.getElement() instanceof IJavaElement) { 187 | elements.add((IJavaElement) match.getElement()); 188 | } 189 | } 190 | }; 191 | SearchEngine searchEngine = new SearchEngine(); 192 | searchEngine.search(pattern, 193 | new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, scope, 194 | requestor, null); 195 | return elements.toArray(new IJavaElement[0]); 196 | } 197 | } catch (BadLocationException | CoreException e) { 198 | // JavaLanguageServerPlugin.logException(e.getMessage(), e); 199 | } 200 | } 201 | } 202 | return null; 203 | } 204 | 205 | public static IJavaSearchScope createSearchScope(IJavaProject project) { 206 | if (project == null) { 207 | return SearchEngine.createWorkspaceScope(); 208 | } 209 | return SearchEngine.createJavaSearchScope(new IJavaProject[] { project }, 210 | IJavaSearchScope.SOURCES | IJavaSearchScope.APPLICATION_LIBRARIES | IJavaSearchScope.SYSTEM_LIBRARIES); 211 | } 212 | 213 | private static String parse(String contents, int offset) { 214 | if (contents == null || offset < 0 || contents.length() < offset 215 | || !isJavaIdentifierOrPeriod(contents.charAt(offset))) { 216 | return null; 217 | } 218 | int start = offset; 219 | while (start - 1 > -1 && isJavaIdentifierOrPeriod(contents.charAt(start - 1))) { 220 | start--; 221 | } 222 | int end = offset; 223 | while (end <= contents.length() && isJavaIdentifierOrPeriod(contents.charAt(end))) { 224 | end++; 225 | } 226 | if (end >= start) { 227 | return contents.substring(start, end); 228 | } 229 | return null; 230 | } 231 | 232 | private static boolean isJavaIdentifierOrPeriod(char ch) { 233 | return Character.isJavaIdentifierPart(ch) || ch == '.'; 234 | } 235 | 236 | public static String disassemble(IClassFile classFile) { 237 | ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); 238 | String disassembledByteCode = null; 239 | try { 240 | disassembledByteCode = disassembler.disassemble(classFile.getBytes(), LF, 241 | ClassFileBytesDisassembler.WORKING_COPY); 242 | disassembledByteCode = MISSING_SOURCES_HEADER + LF + disassembledByteCode; 243 | } catch (Exception e) { 244 | // JavaLanguageServerPlugin.logError("Unable to disassemble " + 245 | // classFile.getHandleIdentifier()); 246 | e.printStackTrace(); 247 | } 248 | return disassembledByteCode; 249 | } 250 | 251 | } 252 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jdt/src/org/eclipse/codelens/jdt/internal/JavaCodeLens.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.jdt.internal; 2 | 3 | import org.eclipse.jface.text.provisional.codelens.CodeLens; 4 | import org.eclipse.jface.text.provisional.codelens.Range; 5 | 6 | public class JavaCodeLens extends CodeLens { 7 | 8 | private final String type; 9 | 10 | public JavaCodeLens(Range range, String type) { 11 | super(range); 12 | this.type = type; 13 | } 14 | 15 | @Override 16 | public void open() { 17 | // TODO Auto-generated method stub 18 | 19 | } 20 | 21 | public String getType() { 22 | return type; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jdt/src/org/eclipse/codelens/jdt/internal/JavaCodeLensController.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.jdt.internal; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | import org.eclipse.codelens.editors.AbstractCodeLensController; 6 | import org.eclipse.codelens.editors.EditorCodeLensContext; 7 | import org.eclipse.codelens.editors.ICodeLensController; 8 | import org.eclipse.core.runtime.IProgressMonitor; 9 | import org.eclipse.jdt.core.dom.CompilationUnit; 10 | import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor; 11 | import org.eclipse.jdt.internal.ui.text.java.IJavaReconcilingListener; 12 | import org.eclipse.jface.text.provisional.codelens.CodeLensStrategy; 13 | import org.eclipse.ui.texteditor.ITextEditor; 14 | 15 | public class JavaCodeLensController extends AbstractCodeLensController implements IJavaReconcilingListener { 16 | 17 | private IProgressMonitor monitor; 18 | private boolean listenerAdded; 19 | 20 | public JavaCodeLensController(CompilationUnitEditor textEditor) { 21 | super((ITextEditor )textEditor); 22 | super.addTarget("java.codelens"); 23 | } 24 | 25 | @Override 26 | public void setProgressMonitor(IProgressMonitor monitor) { 27 | this.monitor = monitor; 28 | getStrategy().setProgressMonitor(monitor); 29 | } 30 | 31 | @Override 32 | public void uninstall() { 33 | if (monitor != null) { 34 | monitor.setCanceled(true); 35 | } 36 | removeReconcileListener((CompilationUnitEditor) getTextEditor()); 37 | getStrategy().dispose(); 38 | } 39 | 40 | @Override 41 | public void refresh() { 42 | getStrategy().initialReconcile(); 43 | if (!listenerAdded) { 44 | addReconcileListener((CompilationUnitEditor) getTextEditor()); 45 | listenerAdded = true; 46 | } 47 | } 48 | 49 | @Override 50 | public void aboutToBeReconciled() { 51 | 52 | } 53 | 54 | @Override 55 | public void reconciled(CompilationUnit ast, boolean forced, IProgressMonitor progressMonitor) { 56 | refresh(); 57 | } 58 | 59 | private void addReconcileListener(CompilationUnitEditor textEditor) { 60 | try { 61 | Method m = CompilationUnitEditor.class.getDeclaredMethod("addReconcileListener", 62 | IJavaReconcilingListener.class); 63 | m.setAccessible(true); 64 | m.invoke(textEditor, this); 65 | } catch (Exception e) { 66 | // TODO Auto-generated catch block 67 | e.printStackTrace(); 68 | } 69 | } 70 | 71 | private void removeReconcileListener(CompilationUnitEditor textEditor) { 72 | try { 73 | Method m = CompilationUnitEditor.class.getDeclaredMethod("removeReconcileListener", 74 | IJavaReconcilingListener.class); 75 | m.setAccessible(true); 76 | m.invoke(textEditor, this); 77 | } catch (Exception e) { 78 | // TODO Auto-generated catch block 79 | e.printStackTrace(); 80 | } 81 | } 82 | 83 | @Override 84 | public void install() { 85 | // TODO Auto-generated method stub 86 | 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jdt/src/org/eclipse/codelens/jdt/internal/JavaCodeLensControllerProvider.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.jdt.internal; 2 | 3 | import org.eclipse.codelens.editors.ICodeLensController; 4 | import org.eclipse.codelens.editors.ICodeLensControllerFactory; 5 | import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor; 6 | import org.eclipse.ui.texteditor.ITextEditor; 7 | 8 | public class JavaCodeLensControllerProvider implements ICodeLensControllerFactory { 9 | 10 | @Override 11 | public boolean isRelevant(ITextEditor textEditor) { 12 | return textEditor instanceof CompilationUnitEditor; 13 | } 14 | 15 | @Override 16 | public ICodeLensController create(ITextEditor textEditor) { 17 | return new JavaCodeLensController((CompilationUnitEditor) textEditor); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jdt/src/org/eclipse/codelens/jdt/internal/JavaCodeLensProvider.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.jdt.internal; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | import javax.tools.DocumentationTool.Location; 8 | 9 | import org.eclipse.codelens.editors.IEditorCodeLensContext; 10 | import org.eclipse.core.resources.ResourcesPlugin; 11 | import org.eclipse.core.runtime.CoreException; 12 | import org.eclipse.core.runtime.IProgressMonitor; 13 | import org.eclipse.jdt.core.Flags; 14 | import org.eclipse.jdt.core.ICompilationUnit; 15 | import org.eclipse.jdt.core.IJavaElement; 16 | import org.eclipse.jdt.core.IJavaProject; 17 | import org.eclipse.jdt.core.ISourceRange; 18 | import org.eclipse.jdt.core.ISourceReference; 19 | import org.eclipse.jdt.core.IType; 20 | import org.eclipse.jdt.core.ITypeRoot; 21 | import org.eclipse.jdt.core.JavaCore; 22 | import org.eclipse.jdt.core.JavaModelException; 23 | import org.eclipse.jdt.core.search.IJavaSearchConstants; 24 | import org.eclipse.jdt.core.search.IJavaSearchScope; 25 | import org.eclipse.jdt.core.search.SearchEngine; 26 | import org.eclipse.jdt.core.search.SearchMatch; 27 | import org.eclipse.jdt.core.search.SearchParticipant; 28 | import org.eclipse.jdt.core.search.SearchPattern; 29 | import org.eclipse.jdt.core.search.SearchRequestor; 30 | import org.eclipse.jdt.internal.junit.util.CoreTestSearchEngine; 31 | import org.eclipse.jdt.junit.JUnitCore; 32 | import org.eclipse.jface.text.provisional.codelens.AbstractSyncCodeLensProvider; 33 | import org.eclipse.jface.text.provisional.codelens.Command; 34 | import org.eclipse.jface.text.provisional.codelens.ICodeLens; 35 | import org.eclipse.jface.text.provisional.codelens.ICodeLensContext; 36 | import org.eclipse.jface.text.provisional.codelens.Range; 37 | 38 | /** 39 | * 40 | * @see https://github.com/eclipse/eclipse.jdt.ls/blob/master/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/CodeLensHandler.java 41 | * 42 | */ 43 | public class JavaCodeLensProvider extends AbstractSyncCodeLensProvider { 44 | 45 | private static final String IMPLEMENTATION_TYPE = "implementations"; 46 | private static final String REFERENCES_TYPE = "references"; 47 | 48 | @Override 49 | protected ICodeLens[] provideSyncCodeLenses(ICodeLensContext context, IProgressMonitor monitor) { 50 | // try { 51 | // Thread.sleep(1000); 52 | // } catch (InterruptedException e1) { 53 | // // TODO Auto-generated catch block 54 | // e1.printStackTrace(); 55 | // } 56 | ITypeRoot unit = JDTUtils.resolveCompilationUnit(((IEditorCodeLensContext) context).getTextEditor()); 57 | if (unit == null || /* !unit.getResource().exists() || */ monitor.isCanceled()) { 58 | return null; 59 | } 60 | try { 61 | IJavaElement[] elements = unit.getChildren(); 62 | List lenses = new ArrayList<>(elements.length); 63 | collectCodeLenses(unit, elements, lenses, monitor); 64 | if (monitor.isCanceled()) { 65 | lenses.clear(); 66 | } 67 | 68 | try { 69 | if (CoreTestSearchEngine.isTestOrTestSuite(unit.findPrimaryType())) { 70 | IType[] tests = JUnitCore.findTestTypes(unit, monitor); 71 | System.err.println(tests); 72 | } 73 | } catch (Exception e) { 74 | // TODO Auto-generated catch block 75 | e.printStackTrace(); 76 | } 77 | 78 | return lenses.toArray(new ICodeLens[lenses.size()]); 79 | } catch (JavaModelException e) { 80 | // JavaLanguageServerPlugin.logException("Problem getting code lenses for" + 81 | // unit.getElementName(), e); 82 | e.printStackTrace(); 83 | } 84 | return null; 85 | } 86 | 87 | private void collectCodeLenses(ITypeRoot unit, IJavaElement[] elements, List lenses, 88 | IProgressMonitor monitor) throws JavaModelException { 89 | for (IJavaElement element : elements) { 90 | if (monitor.isCanceled()) { 91 | return; 92 | } 93 | if (element.getElementType() == IJavaElement.TYPE) { 94 | collectCodeLenses(unit, ((IType) element).getChildren(), lenses, monitor); 95 | } else if (element.getElementType() != IJavaElement.METHOD || JDTUtils.isHiddenGeneratedElement(element)) { 96 | continue; 97 | } 98 | 99 | // if (preferenceManager.getPreferences().isReferencesCodeLensEnabled()) { 100 | ICodeLens lens = getCodeLens(REFERENCES_TYPE, element, unit); 101 | lenses.add(lens); 102 | // } 103 | // if (preferenceManager.getPreferences().isImplementationsCodeLensEnabled() && 104 | // element instanceof IType) { 105 | if (element instanceof IType) { 106 | IType type = (IType) element; 107 | if (type.isInterface() || Flags.isAbstract(type.getFlags())) { 108 | lens = getCodeLens(IMPLEMENTATION_TYPE, element, unit); 109 | lenses.add(lens); 110 | } 111 | } 112 | } 113 | } 114 | 115 | private ICodeLens getCodeLens(String type, IJavaElement element, ITypeRoot unit) throws JavaModelException { 116 | ISourceRange r = ((ISourceReference) element).getNameRange(); 117 | final Range range = JDTUtils.toRange(unit, r.getOffset(), r.getLength()); 118 | 119 | ICodeLens lens = new JavaCodeLens(range, type); 120 | 121 | // String uri = ResourceUtils.toClientUri(JDTUtils.getFileURI(unit)); 122 | // lens.setData(Arrays.asList(uri, range.getStart(), type)); 123 | return lens; 124 | } 125 | 126 | @Override 127 | protected ICodeLens resolveSyncCodeLens(ICodeLensContext context, ICodeLens lens, IProgressMonitor monitor) { 128 | if (lens == null) { 129 | return null; 130 | } 131 | ITypeRoot unit = JDTUtils.resolveCompilationUnit(((IEditorCodeLensContext) context).getTextEditor()); 132 | if (unit == null) { 133 | return lens; 134 | } 135 | Range range = lens.getRange(); 136 | try { 137 | IJavaElement element = JDTUtils.findElementAtSelection(unit, range); 138 | JavaCodeLens javaLens = ((JavaCodeLens) lens); 139 | String type = javaLens.getType(); 140 | if (REFERENCES_TYPE.equals(type)) { 141 | List references = findReferences(element, monitor); 142 | int refCount = references.size(); 143 | javaLens.setCommand(new Command(refCount + " references", "")); 144 | } else if (IMPLEMENTATION_TYPE.equals(type)) { 145 | if (element instanceof IType) { 146 | List references = findImplementations((IType) element, monitor); 147 | int refCount = references.size(); 148 | javaLens.setCommand(new Command(refCount + " implementations", "")); 149 | } 150 | } 151 | 152 | } catch (Exception e) { 153 | // TODO Auto-generated catch block 154 | e.printStackTrace(); 155 | } 156 | return lens; 157 | } 158 | 159 | private List findReferences(IJavaElement element, IProgressMonitor monitor) 160 | throws JavaModelException, CoreException { 161 | if (element == null) { 162 | return Collections.emptyList(); 163 | } 164 | SearchPattern pattern = SearchPattern.createPattern(element, IJavaSearchConstants.REFERENCES); 165 | final List result = new ArrayList<>(); 166 | SearchEngine engine = new SearchEngine(); 167 | engine.search(pattern, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, 168 | createSearchScope(), new SearchRequestor() { 169 | 170 | @Override 171 | public void acceptSearchMatch(SearchMatch match) throws CoreException { 172 | Object o = match.getElement(); 173 | if (o instanceof IJavaElement) { 174 | IJavaElement element = (IJavaElement) o; 175 | ICompilationUnit compilationUnit = (ICompilationUnit) element 176 | .getAncestor(IJavaElement.COMPILATION_UNIT); 177 | if (compilationUnit == null) { 178 | return; 179 | } 180 | Location location = null; // JDTUtils.toLocation(compilationUnit, match.getOffset(), 181 | // match.getLength()); 182 | result.add(location); 183 | } 184 | } 185 | }, monitor); 186 | 187 | return result; 188 | } 189 | 190 | private List findImplementations(IType type, IProgressMonitor monitor) throws JavaModelException { 191 | IType[] results = type.newTypeHierarchy(monitor).getAllSubtypes(type); 192 | final List result = new ArrayList<>(); 193 | for (IType t : results) { 194 | ICompilationUnit compilationUnit = (ICompilationUnit) t.getAncestor(IJavaElement.COMPILATION_UNIT); 195 | if (compilationUnit == null) { 196 | continue; 197 | } 198 | Location location = null; // JDTUtils.toLocation(t); 199 | result.add(location); 200 | } 201 | return result; 202 | } 203 | 204 | private IJavaSearchScope createSearchScope() throws JavaModelException { 205 | IJavaProject[] projects = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()).getJavaProjects(); 206 | return SearchEngine.createJavaSearchScope(projects, IJavaSearchScope.SOURCES); 207 | } 208 | 209 | } 210 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jface.fragment/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jface.fragment/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /target/ -------------------------------------------------------------------------------- /org.eclipse.codelens.jface.fragment/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.eclipse.codelens.jface.fragment 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.pde.ManifestBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.pde.SchemaBuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.m2e.core.maven2Builder 25 | 26 | 27 | 28 | 29 | 30 | org.eclipse.m2e.core.maven2Nature 31 | org.eclipse.pde.PluginNature 32 | org.eclipse.jdt.core.javanature 33 | 34 | 35 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jface.fragment/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jface.fragment/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jface.fragment/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Name: Fragment 4 | Bundle-SymbolicName: org.eclipse.codelens.jface.fragment 5 | Bundle-Version: 1.1.0.qualifier 6 | Fragment-Host: org.eclipse.jface.text 7 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 8 | Bundle-ClassPath: . 9 | Import-Package: javassist, 10 | javassist.bytecode, 11 | javassist.bytecode.analysis, 12 | javassist.bytecode.annotation, 13 | javassist.bytecode.stackmap, 14 | javassist.compiler, 15 | javassist.compiler.ast, 16 | javassist.convert, 17 | javassist.expr, 18 | javassist.runtime, 19 | javassist.scopedpool, 20 | javassist.tools, 21 | javassist.tools.reflect, 22 | javassist.tools.rmi, 23 | javassist.tools.web, 24 | javassist.util, 25 | javassist.util.proxy 26 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jface.fragment/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/ 2 | output.. = bin/ 3 | bin.includes = META-INF/,\ 4 | . 5 | -------------------------------------------------------------------------------- /org.eclipse.codelens.jface.fragment/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | org.eclipse.codelens.jface.fragment 4 | eclipse-plugin 5 | 6 | fr.opensagres.js 7 | codelens 8 | 1.1.0-SNAPSHOT 9 | 10 | 11 | -------------------------------------------------------------------------------- /org.eclipse.codelens.lsp4e/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /org.eclipse.codelens.lsp4e/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /target/ -------------------------------------------------------------------------------- /org.eclipse.codelens.lsp4e/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.eclipse.codelens.ls4pe 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.pde.ManifestBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.pde.SchemaBuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.m2e.core.maven2Builder 25 | 26 | 27 | 28 | 29 | 30 | org.eclipse.m2e.core.maven2Nature 31 | org.eclipse.pde.PluginNature 32 | org.eclipse.jdt.core.javanature 33 | 34 | 35 | -------------------------------------------------------------------------------- /org.eclipse.codelens.lsp4e/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate 4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.compliance=1.8 7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 12 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 13 | org.eclipse.jdt.core.compiler.source=1.8 14 | -------------------------------------------------------------------------------- /org.eclipse.codelens.lsp4e/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /org.eclipse.codelens.lsp4e/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Vendor: %providerName 4 | Bundle-SymbolicName: org.eclipse.codelens.ls4pe;singleton:=true 5 | Bundle-Version: 1.1.0.qualifier 6 | Require-Bundle: org.eclipse.core.runtime, 7 | org.eclipse.jface.text, 8 | org.eclipse.jface, 9 | org.eclipse.codelens, 10 | org.eclipse.ui.ide, 11 | org.eclipse.ui.workbench, 12 | org.eclipse.ui.workbench.texteditor, 13 | org.eclipse.codelens.editors, 14 | org.eclipse.core.resources, 15 | org.eclipse.lsp4e, 16 | org.eclipse.lsp4j 17 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 18 | Import-Package: javassist, 19 | javassist.bytecode, 20 | javassist.bytecode.analysis, 21 | javassist.bytecode.annotation, 22 | javassist.bytecode.stackmap, 23 | javassist.compiler, 24 | javassist.compiler.ast, 25 | javassist.convert, 26 | javassist.expr, 27 | javassist.runtime, 28 | javassist.scopedpool, 29 | javassist.tools, 30 | javassist.tools.reflect, 31 | javassist.tools.rmi, 32 | javassist.tools.web, 33 | javassist.util, 34 | javassist.util.proxy, 35 | org.eclipse.swt, 36 | org.eclipse.swt.custom, 37 | org.eclipse.swt.events, 38 | org.eclipse.swt.graphics, 39 | org.eclipse.swt.widgets 40 | Bundle-ClassPath: . 41 | Bundle-Name: %pluginName 42 | Bundle-ActivationPolicy: lazy 43 | -------------------------------------------------------------------------------- /org.eclipse.codelens.lsp4e/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/ 2 | output.. = bin/ 3 | bin.includes = .,\ 4 | plugin.xml,\ 5 | plugin.properties,\ 6 | META-INF/ 7 | -------------------------------------------------------------------------------- /org.eclipse.codelens.lsp4e/plugin.properties: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Copyright (c) 2015-2017 Angelo Zerr and others. 3 | # All rights reserved. This program and the accompanying materials 4 | # are made available under the terms of the Eclipse Public License v1.0 5 | # which accompanies this distribution, and is available at 6 | # http://www.eclipse.org/legal/epl-v10.html 7 | # 8 | # Contributors: 9 | # Angelo Zerr - Initial API and implementation 10 | ############################################################################### 11 | pluginName=Eclipse CodeLens - JDT 12 | providerName=Angelo ZERR -------------------------------------------------------------------------------- /org.eclipse.codelens.lsp4e/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | 16 | 17 | 19 | 21 | 22 | 23 | 24 | 26 | 27 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /org.eclipse.codelens.lsp4e/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | org.eclipse.codelens.ls4pe 4 | eclipse-plugin 5 | 6 | fr.opensagres.js 7 | codelens 8 | 1.1.0-SNAPSHOT 9 | 10 | 11 | -------------------------------------------------------------------------------- /org.eclipse.codelens.lsp4e/src/org/eclipse/codelens/lsp4e/internal/LSPCodeLens.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.lsp4e.internal; 2 | 3 | import org.eclipse.jface.text.provisional.codelens.CodeLens; 4 | import org.eclipse.jface.text.provisional.codelens.Range; 5 | import org.eclipse.lsp4j.Command; 6 | 7 | public class LSPCodeLens extends CodeLens { 8 | 9 | private org.eclipse.lsp4j.CodeLens cl; 10 | 11 | public LSPCodeLens(org.eclipse.lsp4j.CodeLens cl) { 12 | super(toRange(cl)); 13 | update(cl); 14 | this.cl = cl; 15 | } 16 | 17 | private static Range toRange(org.eclipse.lsp4j.CodeLens cl) { 18 | org.eclipse.lsp4j.Range range = cl.getRange(); 19 | return new Range(range.getStart().getLine() + 1, range.getStart().getCharacter()); 20 | } 21 | 22 | @Override 23 | public void open() { 24 | // TODO Auto-generated method stub 25 | 26 | } 27 | 28 | public org.eclipse.lsp4j.CodeLens getCl() { 29 | return cl; 30 | } 31 | 32 | public void update(org.eclipse.lsp4j.CodeLens cl) { 33 | Command command = cl.getCommand(); 34 | if (command != null) { 35 | org.eclipse.jface.text.provisional.codelens.Command c = new org.eclipse.jface.text.provisional.codelens.Command( 36 | command.getTitle(), command.getCommand()); 37 | super.setCommand(c); 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /org.eclipse.codelens.lsp4e/src/org/eclipse/codelens/lsp4e/internal/LSPCodeLensControllerProvider.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.lsp4e.internal; 2 | 3 | import java.util.Collection; 4 | 5 | import org.eclipse.codelens.editors.DefaultCodeLensController; 6 | import org.eclipse.codelens.editors.ICodeLensController; 7 | import org.eclipse.codelens.editors.ICodeLensControllerFactory; 8 | import org.eclipse.lsp4e.LSPEclipseUtils; 9 | import org.eclipse.lsp4e.LanguageServiceAccessor; 10 | import org.eclipse.lsp4e.LanguageServiceAccessor.LSPDocumentInfo; 11 | import org.eclipse.ui.texteditor.ITextEditor; 12 | 13 | public class LSPCodeLensControllerProvider implements ICodeLensControllerFactory { 14 | 15 | @Override 16 | public boolean isRelevant(ITextEditor textEditor) { 17 | Collection infos = LanguageServiceAccessor.getLSPDocumentInfosFor( 18 | LSPEclipseUtils.getDocument(textEditor), 19 | capabilities -> capabilities.getCodeLensProvider() != null); 20 | return (!infos.isEmpty()); 21 | } 22 | 23 | @Override 24 | public ICodeLensController create(ITextEditor textEditor) { 25 | DefaultCodeLensController controller = new DefaultCodeLensController(textEditor); 26 | controller.addTarget("lsp4e.codelens"); 27 | return controller; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /org.eclipse.codelens.lsp4e/src/org/eclipse/codelens/lsp4e/internal/LSPCodeLensProvider.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.lsp4e.internal; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.List; 6 | import java.util.concurrent.CompletableFuture; 7 | 8 | import org.eclipse.codelens.editors.IEditorCodeLensContext; 9 | import org.eclipse.core.runtime.IProgressMonitor; 10 | import org.eclipse.jface.text.provisional.codelens.ICodeLens; 11 | import org.eclipse.jface.text.provisional.codelens.ICodeLensContext; 12 | import org.eclipse.jface.text.provisional.codelens.ICodeLensProvider; 13 | import org.eclipse.lsp4e.LSPEclipseUtils; 14 | import org.eclipse.lsp4e.LanguageServiceAccessor; 15 | import org.eclipse.lsp4e.LanguageServiceAccessor.LSPDocumentInfo; 16 | import org.eclipse.lsp4j.CodeLens; 17 | import org.eclipse.lsp4j.CodeLensParams; 18 | import org.eclipse.lsp4j.TextDocumentIdentifier; 19 | import org.eclipse.ui.texteditor.ITextEditor; 20 | 21 | public class LSPCodeLensProvider implements ICodeLensProvider { 22 | 23 | @Override 24 | public CompletableFuture provideCodeLenses(ICodeLensContext context, IProgressMonitor monitor) { 25 | ITextEditor textEditor = ((IEditorCodeLensContext) context).getTextEditor(); 26 | 27 | LSPDocumentInfo info = null; 28 | Collection infos = LanguageServiceAccessor.getLSPDocumentInfosFor( 29 | LSPEclipseUtils.getDocument((ITextEditor) textEditor), 30 | capabilities -> capabilities.getCodeLensProvider() != null); 31 | if (!infos.isEmpty()) { 32 | info = infos.iterator().next(); 33 | } else { 34 | info = null; 35 | } 36 | if (info != null) { 37 | 38 | CodeLensParams param = new CodeLensParams(new TextDocumentIdentifier(info.getFileUri().toString())); 39 | final CompletableFuture> codeLens = info.getLanguageClient() 40 | .getTextDocumentService().codeLens(param); 41 | return codeLens.thenApply(lens -> { 42 | List lenses = new ArrayList<>(); 43 | for (CodeLens cl : lens) { 44 | lenses.add(new LSPCodeLens(cl)); 45 | } 46 | return lenses.toArray(new ICodeLens[lenses.size()]); 47 | }); 48 | // try { 49 | // 50 | // 51 | // 52 | // List lenses = new ArrayList<>(); 53 | // List lens = codeLens.get(5000, TimeUnit.MILLISECONDS); 54 | // for (CodeLens cl : lens) { 55 | // lenses.add(new LSPCodeLens(cl)); 56 | // } 57 | // return lenses.toArray(new ICodeLens[lenses.size()]); 58 | // } catch (Exception e) { 59 | // // TODO Auto-generated catch block 60 | // e.printStackTrace(); 61 | // } 62 | 63 | } 64 | return null; 65 | } 66 | 67 | @Override 68 | public CompletableFuture resolveCodeLens(ICodeLensContext context, ICodeLens codeLens, 69 | IProgressMonitor monitor) { 70 | ITextEditor textEditor = ((IEditorCodeLensContext) context).getTextEditor(); 71 | 72 | LSPDocumentInfo info = null; 73 | Collection infos = LanguageServiceAccessor.getLSPDocumentInfosFor( 74 | LSPEclipseUtils.getDocument((ITextEditor) textEditor), 75 | capabilities -> capabilities.getCodeLensProvider() != null 76 | && capabilities.getCodeLensProvider().isResolveProvider()); 77 | if (!infos.isEmpty()) { 78 | info = infos.iterator().next(); 79 | } else { 80 | info = null; 81 | } 82 | if (info != null) { 83 | LSPCodeLens lscl = ((LSPCodeLens) codeLens); 84 | CodeLens unresolved = lscl.getCl(); 85 | return info.getLanguageClient().getTextDocumentService().resolveCodeLens(unresolved).thenApply(resolved -> { 86 | lscl.update(resolved); 87 | return lscl; 88 | }); 89 | } 90 | return null; 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /org.eclipse.codelens.repository/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /org.eclipse.codelens.repository/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /org.eclipse.codelens.repository/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.eclipse.codelens.repository 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /org.eclipse.codelens.repository/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 3 | org.eclipse.jdt.core.compiler.compliance=1.5 4 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 5 | org.eclipse.jdt.core.compiler.source=1.5 6 | -------------------------------------------------------------------------------- /org.eclipse.codelens.repository/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /org.eclipse.codelens.repository/category.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /org.eclipse.codelens.repository/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | fr.opensagres.js 6 | codelens 7 | 1.1.0-SNAPSHOT 8 | 9 | org.eclipse.codelens.repository 10 | eclipse-repository 11 | 12 | snapshots 13 | 14 | 15 | 16 | 17 | 18 | org.apache.maven.wagon 19 | wagon-ftp 20 | 2.9 21 | 22 | 23 | 24 | 25 | 26 | 27 | uploadRepo 28 | 29 | 30 | ftp://ftp.online.net 31 | /oss/${project.artifactId}/${url.suffix} 32 | 33 | ${project.build.directory}/repository/ 34 | 35 | 36 | 37 | 38 | 39 | org.codehaus.mojo 40 | wagon-maven-plugin 41 | 1.0 42 | 43 | 44 | upload-repo 45 | install 46 | 47 | upload 48 | 49 | 50 | ${repo.path} 51 | ** 52 | ${ftp.toDir} 53 | ${ftp.url} 54 | p2Repo 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | release 64 | 65 | releases 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /org.eclipse.codelens.samples/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /org.eclipse.codelens.samples/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | -------------------------------------------------------------------------------- /org.eclipse.codelens.samples/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.eclipse.codelens.samples 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.pde.ManifestBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.pde.SchemaBuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.pde.PluginNature 26 | org.eclipse.jdt.core.javanature 27 | 28 | 29 | -------------------------------------------------------------------------------- /org.eclipse.codelens.samples/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate 4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.compliance=1.8 7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 12 | org.eclipse.jdt.core.compiler.source=1.8 13 | -------------------------------------------------------------------------------- /org.eclipse.codelens.samples/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Name: Eclipse CodeLens Samples 4 | Bundle-SymbolicName: org.eclipse.codelens.samples;singleton:=true 5 | Bundle-Version: 1.0.0.qualifier 6 | Require-Bundle: org.eclipse.codelens;bundle-version="1.0.0", 7 | org.eclipse.swt, 8 | org.eclipse.jface.text;bundle-version="3.11.1", 9 | org.eclipse.core.runtime, 10 | org.eclipse.jface 11 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 12 | -------------------------------------------------------------------------------- /org.eclipse.codelens.samples/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/ 2 | output.. = bin/ 3 | bin.includes = plugin.xml,\ 4 | META-INF/,\ 5 | . 6 | -------------------------------------------------------------------------------- /org.eclipse.codelens.samples/src/org/eclipse/codelens/samples/ClassCodeLens.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.samples; 2 | 3 | import org.eclipse.jface.dialogs.MessageDialog; 4 | import org.eclipse.jface.text.provisional.codelens.CodeLens; 5 | import org.eclipse.swt.widgets.Display; 6 | 7 | public class ClassCodeLens extends CodeLens { 8 | 9 | private String className; 10 | 11 | public ClassCodeLens(String className, int startLineNumber) { 12 | super(startLineNumber); 13 | this.className = className; 14 | } 15 | 16 | public String getClassName() { 17 | return className; 18 | } 19 | 20 | @Override 21 | public void open() { 22 | Display.getDefault().asyncExec(new Runnable() { 23 | 24 | @Override 25 | public void run() { 26 | MessageDialog.openInformation(Display.getDefault().getActiveShell(), "Open class CodeLens", ClassCodeLens.this.className); 27 | 28 | } 29 | }); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /org.eclipse.codelens.samples/src/org/eclipse/codelens/samples/ClassImplementationsCodeLensProvider.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.samples; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.eclipse.core.runtime.IProgressMonitor; 7 | import org.eclipse.jface.text.IDocument; 8 | import org.eclipse.jface.text.ITextViewer; 9 | import org.eclipse.jface.text.provisional.codelens.AbstractSyncCodeLensProvider; 10 | import org.eclipse.jface.text.provisional.codelens.Command; 11 | import org.eclipse.jface.text.provisional.codelens.ICodeLens; 12 | import org.eclipse.jface.text.provisional.codelens.ICodeLensContext; 13 | 14 | public class ClassImplementationsCodeLensProvider extends AbstractSyncCodeLensProvider { 15 | 16 | @Override 17 | public ICodeLens[] provideSyncCodeLenses(ICodeLensContext context, IProgressMonitor monitor) { 18 | ITextViewer textViewer = context.getViewer(); 19 | IDocument document = textViewer.getDocument(); 20 | List lenses = new ArrayList<>(); 21 | int lineCount = document.getNumberOfLines(); 22 | for (int i = 0; i < lineCount; i++) { 23 | updateCodeLens(i, document, "class ", lenses); 24 | updateCodeLens(i, document, "interface ", lenses); 25 | } 26 | return lenses.toArray(new ICodeLens[0]); 27 | } 28 | 29 | private void updateCodeLens(int lineIndex, IDocument document, String token, List lenses) { 30 | String line = getLineText(document, lineIndex, false); 31 | int index = line.indexOf(token); 32 | if (index != -1) { 33 | String className = line.substring(index + token.length(), line.length()); 34 | index = className.indexOf(" "); 35 | if (index != -1) { 36 | className = className.substring(0, index); 37 | } 38 | if (className.length() > 0) { 39 | lenses.add(new ClassCodeLens(className, lineIndex + 1)); 40 | } 41 | } 42 | } 43 | 44 | @Override 45 | public ICodeLens resolveSyncCodeLens(ICodeLensContext context, ICodeLens codeLens, IProgressMonitor monitor) { 46 | ITextViewer textViewer = context.getViewer(); 47 | IDocument document = textViewer.getDocument(); 48 | String className = ((ClassCodeLens) codeLens).getClassName(); 49 | int refCount = 0; 50 | int lineCount = document.getNumberOfLines(); 51 | for (int i = 0; i < lineCount; i++) { 52 | String line = getLineText(document, i, false); 53 | refCount += line.contains("implements " + className) ? 1 : 0; 54 | } 55 | ((ClassCodeLens) codeLens).setCommand(new Command(refCount + " implementation", "")); 56 | return codeLens; 57 | } 58 | 59 | private static String getLineText(IDocument document, int line, boolean withLineDelimiter) { 60 | try { 61 | int lo = document.getLineOffset(line); 62 | int ll = document.getLineLength(line); 63 | if (!withLineDelimiter) { 64 | String delim = document.getLineDelimiter(line); 65 | ll = ll - (delim != null ? delim.length() : 0); 66 | } 67 | return document.get(lo, ll); 68 | } catch (Exception e) { 69 | e.printStackTrace(); 70 | return null; 71 | } 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /org.eclipse.codelens.samples/src/org/eclipse/codelens/samples/ClassReferencesCodeLensProvider.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.samples; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.eclipse.core.runtime.IProgressMonitor; 7 | import org.eclipse.jface.text.IDocument; 8 | import org.eclipse.jface.text.ITextViewer; 9 | import org.eclipse.jface.text.provisional.codelens.AbstractSyncCodeLensProvider; 10 | import org.eclipse.jface.text.provisional.codelens.Command; 11 | import org.eclipse.jface.text.provisional.codelens.ICodeLens; 12 | import org.eclipse.jface.text.provisional.codelens.ICodeLensContext; 13 | 14 | public class ClassReferencesCodeLensProvider extends AbstractSyncCodeLensProvider { 15 | 16 | @Override 17 | public ICodeLens[] provideSyncCodeLenses(ICodeLensContext context, IProgressMonitor monitor) { 18 | ITextViewer textViewer = context.getViewer(); 19 | IDocument document = textViewer.getDocument(); 20 | List lenses = new ArrayList<>(); 21 | int lineCount = document.getNumberOfLines(); 22 | for (int i = 0; i < lineCount; i++) { 23 | String line = getLineText(document, i, false); 24 | int index = line.indexOf("class "); 25 | if (index != -1) { 26 | String className = line.substring(index + "class ".length(), line.length()); 27 | index = className.indexOf(" "); 28 | if (index != -1) { 29 | className = className.substring(0, index); 30 | } 31 | if (className.length() > 0) { 32 | lenses.add(new ClassCodeLens(className, i + 1)); 33 | } 34 | } 35 | } 36 | return lenses.toArray(new ICodeLens[0]); 37 | } 38 | 39 | @Override 40 | public ICodeLens resolveSyncCodeLens(ICodeLensContext context, ICodeLens codeLens, IProgressMonitor monitor) { 41 | ITextViewer textViewer = context.getViewer(); 42 | IDocument document = textViewer.getDocument(); 43 | String className = ((ClassCodeLens) codeLens).getClassName(); 44 | int refCount = 0; 45 | int lineCount = document.getNumberOfLines(); 46 | for (int i = 0; i < lineCount; i++) { 47 | String line = getLineText(document, i, false); 48 | refCount += line.contains("new " + className) ? 1 : 0; 49 | } 50 | ((ClassCodeLens) codeLens).setCommand(new Command(refCount + " references", "")); 51 | return codeLens; 52 | } 53 | 54 | private static String getLineText(IDocument document, int line, boolean withLineDelimiter) { 55 | try { 56 | int lo = document.getLineOffset(line); 57 | int ll = document.getLineLength(line); 58 | if (!withLineDelimiter) { 59 | String delim = document.getLineDelimiter(line); 60 | ll = ll - (delim != null ? delim.length() : 0); 61 | } 62 | return document.get(lo, ll); 63 | } catch (Exception e) { 64 | e.printStackTrace(); 65 | return null; 66 | } 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /org.eclipse.codelens.samples/src/org/eclipse/codelens/samples/CodeLensDemo.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.samples; 2 | 3 | import org.eclipse.jface.text.Document; 4 | import org.eclipse.jface.text.ITextViewer; 5 | import org.eclipse.jface.text.TextViewer; 6 | import org.eclipse.jface.text.provisional.codelens.CodeLensProviderRegistry; 7 | import org.eclipse.jface.text.provisional.codelens.CodeLensStrategy; 8 | import org.eclipse.jface.text.provisional.codelens.DefaultCodeLensContext; 9 | import org.eclipse.swt.SWT; 10 | import org.eclipse.swt.custom.StyledText; 11 | import org.eclipse.swt.events.ModifyEvent; 12 | import org.eclipse.swt.events.ModifyListener; 13 | import org.eclipse.swt.layout.FillLayout; 14 | import org.eclipse.swt.layout.GridData; 15 | import org.eclipse.swt.layout.GridLayout; 16 | import org.eclipse.swt.widgets.Composite; 17 | import org.eclipse.swt.widgets.Display; 18 | import org.eclipse.swt.widgets.Shell; 19 | 20 | public class CodeLensDemo { 21 | 22 | private static final String CONTENT_TYPE_ID = "ts"; 23 | 24 | public static void main(String[] args) throws Exception { 25 | // create the widget's shell 26 | Shell shell = new Shell(); 27 | shell.setLayout(new FillLayout()); 28 | shell.setSize(500, 500); 29 | Display display = shell.getDisplay(); 30 | 31 | Composite parent = new Composite(shell, SWT.NONE); 32 | parent.setLayout(new GridLayout(2, false)); 33 | 34 | ITextViewer textViewer = new TextViewer(parent, SWT.V_SCROLL | SWT.BORDER); 35 | String delim = textViewer.getTextWidget().getLineDelimiter(); 36 | textViewer.setDocument(new Document(delim + " class A" + delim + "new A" + delim + "new A" + delim + "class B" 37 | + delim + "new B" + delim + "interface I" + delim + "class C implements I")); 38 | StyledText styledText = textViewer.getTextWidget(); 39 | styledText.setLayoutData(new GridData(GridData.FILL_BOTH)); 40 | 41 | CodeLensProviderRegistry registry = CodeLensProviderRegistry.getInstance(); 42 | registry.register(CONTENT_TYPE_ID, new ClassReferencesCodeLensProvider()); 43 | registry.register(CONTENT_TYPE_ID, new ClassImplementationsCodeLensProvider()); 44 | 45 | CodeLensStrategy codelens = new CodeLensStrategy(new DefaultCodeLensContext(textViewer), false); 46 | codelens.addTarget(CONTENT_TYPE_ID).reconcile(null); 47 | 48 | styledText.addModifyListener(new ModifyListener() { 49 | 50 | @Override 51 | public void modifyText(ModifyEvent event) { 52 | codelens.reconcile(null); 53 | } 54 | }); 55 | 56 | shell.open(); 57 | while (!shell.isDisposed()) 58 | if (!display.readAndDispatch()) 59 | display.sleep(); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /org.eclipse.codelens.samples/src/org/eclipse/codelens/samples/StyledTextLineSpacingDemo.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.samples; 2 | 3 | import org.eclipse.swt.SWT; 4 | import org.eclipse.swt.custom.StyledText; 5 | import org.eclipse.swt.custom.patch.StyledTextPatcher; 6 | import org.eclipse.swt.custom.provisional.ILineSpacingProvider; 7 | import org.eclipse.swt.layout.FillLayout; 8 | import org.eclipse.swt.layout.GridData; 9 | import org.eclipse.swt.layout.GridLayout; 10 | import org.eclipse.swt.widgets.Composite; 11 | import org.eclipse.swt.widgets.Display; 12 | import org.eclipse.swt.widgets.Shell; 13 | 14 | public class StyledTextLineSpacingDemo { 15 | 16 | public static void main(String[] args) throws Exception { 17 | // create the widget's shell 18 | Shell shell = new Shell(); 19 | shell.setLayout(new FillLayout()); 20 | shell.setSize(500, 500); 21 | Display display = shell.getDisplay(); 22 | 23 | Composite parent = new Composite(shell, SWT.NONE); 24 | parent.setLayout(new GridLayout()); 25 | 26 | StyledText styledText = new StyledText(parent, SWT.BORDER | SWT.V_SCROLL); 27 | styledText.setLayoutData(new GridData(GridData.FILL_BOTH)); 28 | 29 | styledText.setText("a\nb\nc\nd"); 30 | 31 | StyledTextPatcher.setLineSpacingProvider(styledText, new ILineSpacingProvider() { 32 | 33 | @Override 34 | public Integer getLineSpacing(int lineIndex) { 35 | if (lineIndex == 0) { 36 | return 10; 37 | } else if (lineIndex == 1) { 38 | return 30; 39 | } 40 | return null; 41 | } 42 | }); 43 | 44 | shell.open(); 45 | while (!shell.isDisposed()) 46 | if (!display.readAndDispatch()) 47 | display.sleep(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /org.eclipse.codelens.samples/src/org/eclipse/codelens/samples/ViewZoneDemo.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.codelens.samples; 2 | 3 | import org.eclipse.jface.dialogs.InputDialog; 4 | import org.eclipse.jface.text.Document; 5 | import org.eclipse.jface.text.ITextViewer; 6 | import org.eclipse.jface.text.TextViewer; 7 | import org.eclipse.jface.text.provisional.viewzones.DefaultViewZone; 8 | import org.eclipse.jface.text.provisional.viewzones.IViewZone; 9 | import org.eclipse.jface.text.provisional.viewzones.ViewZoneChangeAccessor; 10 | import org.eclipse.jface.window.Window; 11 | import org.eclipse.swt.SWT; 12 | import org.eclipse.swt.custom.StyledText; 13 | import org.eclipse.swt.events.SelectionAdapter; 14 | import org.eclipse.swt.events.SelectionEvent; 15 | import org.eclipse.swt.layout.FillLayout; 16 | import org.eclipse.swt.layout.GridData; 17 | import org.eclipse.swt.layout.GridLayout; 18 | import org.eclipse.swt.widgets.Button; 19 | import org.eclipse.swt.widgets.Composite; 20 | import org.eclipse.swt.widgets.Display; 21 | import org.eclipse.swt.widgets.Shell; 22 | 23 | public class ViewZoneDemo { 24 | 25 | public static void main(String[] args) throws Exception { 26 | // create the widget's shell 27 | Shell shell = new Shell(); 28 | shell.setLayout(new FillLayout()); 29 | shell.setSize(500, 500); 30 | Display display = shell.getDisplay(); 31 | 32 | Composite parent = new Composite(shell, SWT.NONE); 33 | parent.setLayout(new GridLayout(2, false)); 34 | 35 | ITextViewer textViewer = new TextViewer(parent, SWT.V_SCROLL | SWT.BORDER); 36 | textViewer.setDocument(new Document("")); 37 | StyledText styledText = textViewer.getTextWidget(); 38 | styledText.setLayoutData(new GridData(GridData.FILL_BOTH)); 39 | 40 | ViewZoneChangeAccessor viewZones = new ViewZoneChangeAccessor(textViewer); 41 | 42 | Button add = new Button(parent, SWT.NONE); 43 | add.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false, 0, 0)); 44 | add.setText("Add Zone"); 45 | add.addSelectionListener(new SelectionAdapter() { 46 | @Override 47 | public void widgetSelected(SelectionEvent e) { 48 | InputDialog dlg = new InputDialog(Display.getCurrent().getActiveShell(), "", "Enter view zone content", 49 | "Zone " + viewZones.getSize(), null); 50 | if (dlg.open() == Window.OK) { 51 | int line = styledText.getLineAtOffset(styledText.getCaretOffset()); 52 | IViewZone zone = new DefaultViewZone(line, 20, dlg.getValue()); 53 | viewZones.addZone(zone); 54 | viewZones.layoutZone(zone); 55 | } 56 | } 57 | }); 58 | 59 | shell.open(); 60 | while (!shell.isDisposed()) 61 | if (!display.readAndDispatch()) 62 | display.sleep(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /org.eclipse.codelens.swt.fragment/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /org.eclipse.codelens.swt.fragment/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /target/ -------------------------------------------------------------------------------- /org.eclipse.codelens.swt.fragment/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.eclipse.codelens.swt.fragment 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.pde.ManifestBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.pde.SchemaBuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.m2e.core.maven2Builder 25 | 26 | 27 | 28 | 29 | 30 | org.eclipse.m2e.core.maven2Nature 31 | org.eclipse.pde.PluginNature 32 | org.eclipse.jdt.core.javanature 33 | 34 | 35 | -------------------------------------------------------------------------------- /org.eclipse.codelens.swt.fragment/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /org.eclipse.codelens.swt.fragment/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /org.eclipse.codelens.swt.fragment/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Name: Fragment 4 | Bundle-SymbolicName: org.eclipse.codelens.swt.fragment 5 | Bundle-Version: 1.1.0.qualifier 6 | Fragment-Host: org.eclipse.swt 7 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 8 | Bundle-ClassPath: . 9 | Import-Package: javassist, 10 | javassist.bytecode, 11 | javassist.bytecode.analysis, 12 | javassist.bytecode.annotation, 13 | javassist.bytecode.stackmap, 14 | javassist.compiler, 15 | javassist.compiler.ast, 16 | javassist.convert, 17 | javassist.expr, 18 | javassist.runtime, 19 | javassist.scopedpool, 20 | javassist.tools, 21 | javassist.tools.reflect, 22 | javassist.tools.rmi, 23 | javassist.tools.web, 24 | javassist.util, 25 | javassist.util.proxy 26 | -------------------------------------------------------------------------------- /org.eclipse.codelens.swt.fragment/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/ 2 | output.. = bin/ 3 | bin.includes = META-INF/,\ 4 | . 5 | -------------------------------------------------------------------------------- /org.eclipse.codelens.swt.fragment/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | org.eclipse.codelens.swt.fragment 4 | eclipse-plugin 5 | 6 | fr.opensagres.js 7 | codelens 8 | 1.1.0-SNAPSHOT 9 | 10 | 11 | -------------------------------------------------------------------------------- /org.eclipse.codelens/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /org.eclipse.codelens/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /target/ -------------------------------------------------------------------------------- /org.eclipse.codelens/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.eclipse.codelens 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.pde.ManifestBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.pde.SchemaBuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.m2e.core.maven2Builder 25 | 26 | 27 | 28 | 29 | 30 | org.eclipse.m2e.core.maven2Nature 31 | org.eclipse.pde.PluginNature 32 | org.eclipse.jdt.core.javanature 33 | 34 | 35 | -------------------------------------------------------------------------------- /org.eclipse.codelens/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate 4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.compliance=1.8 7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 12 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 13 | org.eclipse.jdt.core.compiler.source=1.8 14 | -------------------------------------------------------------------------------- /org.eclipse.codelens/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /org.eclipse.codelens/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Vendor: %providerName 4 | Bundle-SymbolicName: org.eclipse.codelens;singleton:=true 5 | Bundle-Version: 1.1.0.qualifier 6 | Require-Bundle: org.eclipse.core.runtime, 7 | org.eclipse.jface.text, 8 | org.eclipse.jface 9 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 10 | Import-Package: javassist, 11 | javassist.bytecode, 12 | javassist.bytecode.analysis, 13 | javassist.bytecode.annotation, 14 | javassist.bytecode.stackmap, 15 | javassist.compiler, 16 | javassist.compiler.ast, 17 | javassist.convert, 18 | javassist.expr, 19 | javassist.runtime, 20 | javassist.scopedpool, 21 | javassist.tools, 22 | javassist.tools.reflect, 23 | javassist.tools.rmi, 24 | javassist.tools.web, 25 | javassist.util, 26 | javassist.util.proxy, 27 | org.eclipse.swt, 28 | org.eclipse.swt.custom, 29 | org.eclipse.swt.events, 30 | org.eclipse.swt.graphics, 31 | org.eclipse.swt.widgets 32 | Bundle-ClassPath: . 33 | Export-Package: org.eclipse.jface.text.provisional.codelens, 34 | org.eclipse.jface.text.provisional.viewzones, 35 | org.eclipse.jface.text.source.patch, 36 | org.eclipse.swt.custom.patch, 37 | org.eclipse.swt.custom.provisional 38 | Bundle-Name: %pluginName 39 | Bundle-ActivationPolicy: lazy 40 | -------------------------------------------------------------------------------- /org.eclipse.codelens/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/ 2 | output.. = bin/ 3 | bin.includes = .,\ 4 | META-INF/,\ 5 | plugin.xml,\ 6 | plugin.properties,\ 7 | schema/ 8 | -------------------------------------------------------------------------------- /org.eclipse.codelens/plugin.properties: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Copyright (c) 2015-2017 Angelo Zerr and others. 3 | # All rights reserved. This program and the accompanying materials 4 | # are made available under the terms of the Eclipse Public License v1.0 5 | # which accompanies this distribution, and is available at 6 | # http://www.eclipse.org/legal/epl-v10.html 7 | # 8 | # Contributors: 9 | # Angelo Zerr - Initial API and implementation 10 | ############################################################################### 11 | pluginName=Eclipse CodeLens 12 | providerName=Angelo ZERR 13 | 14 | # Extension Points 15 | CodeLensProviders.extension.name=CodeLens provider extension point. -------------------------------------------------------------------------------- /org.eclipse.codelens/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | 16 | 17 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /org.eclipse.codelens/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | org.eclipse.codelens 4 | eclipse-plugin 5 | 6 | fr.opensagres.js 7 | codelens 8 | 1.1.0-SNAPSHOT 9 | 10 | 11 | -------------------------------------------------------------------------------- /org.eclipse.codelens/schema/codeLensProviders.exsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Extension point to register CodeLens providers. 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | a fully-qualified name of the target extension point 27 | 28 | 29 | 30 | 31 | 32 | 33 | an optional id 34 | 35 | 36 | 37 | 38 | 39 | 40 | an optional name 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | This extension point allows developers to register TextMate grammars. 51 | 52 | 53 | 54 | 55 | 56 | 57 | CodeLens Provider class. 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | Target 68 | 69 | 70 | 71 | 72 | 73 | 74 | CodeLens providers name. 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 2.0 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | This plugin itself does not have any predefined builders. 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/codelens/internal/CodeLensPlugin.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-2016 Angelo ZERR. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * Angelo Zerr - initial API and implementation 10 | * Lorenzo Dalla Vecchia - getter for ProblemManager 11 | */ 12 | package org.eclipse.codelens.internal; 13 | 14 | import org.eclipse.core.runtime.CoreException; 15 | import org.eclipse.core.runtime.IStatus; 16 | import org.eclipse.core.runtime.Plugin; 17 | import org.eclipse.core.runtime.Status; 18 | import org.eclipse.jface.text.provisional.codelens.CodeLensProviderRegistry; 19 | import org.osgi.framework.BundleContext; 20 | 21 | /** 22 | * The activator class controls the plug-in life cycle 23 | */ 24 | public class CodeLensPlugin extends Plugin { 25 | 26 | public static final String PLUGIN_ID = "org.eclipse.codelens"; //$NON-NLS-1$ 27 | 28 | // The shared instance. 29 | private static CodeLensPlugin plugin; 30 | 31 | /** 32 | * The constructor. 33 | */ 34 | public CodeLensPlugin() { 35 | super(); 36 | plugin = this; 37 | } 38 | 39 | @Override 40 | public void start(BundleContext context) throws Exception { 41 | super.start(context); 42 | CodeLensProviderRegistry.getInstance().initialize(); 43 | } 44 | 45 | @Override 46 | public void stop(BundleContext context) throws Exception { 47 | CodeLensProviderRegistry.getInstance().initialize(); 48 | plugin = null; 49 | super.stop(context); 50 | } 51 | 52 | /** 53 | * Returns the shared instance 54 | * 55 | * @return the shared instance 56 | */ 57 | public static CodeLensPlugin getDefault() { 58 | return plugin; 59 | } 60 | 61 | public static void log(IStatus status) { 62 | CodeLensPlugin plugin = getDefault(); 63 | if (plugin != null) { 64 | plugin.getLog().log(status); 65 | } else { 66 | System.err.println(status.getPlugin() + ": " + status.getMessage()); //$NON-NLS-1$ 67 | } 68 | } 69 | 70 | public static void log(Throwable e) { 71 | if (e instanceof CoreException) { 72 | log(new Status(IStatus.ERROR, PLUGIN_ID, ((CoreException) e).getStatus().getSeverity(), e.getMessage(), 73 | e.getCause())); 74 | } else { 75 | log(new Status(IStatus.ERROR, PLUGIN_ID, e.getMessage(), e)); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/codelens/AbstractSyncCodeLensProvider.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.codelens; 2 | 3 | import java.util.concurrent.CompletableFuture; 4 | 5 | import org.eclipse.core.runtime.IProgressMonitor; 6 | 7 | public abstract class AbstractSyncCodeLensProvider implements ICodeLensProvider { 8 | 9 | @Override 10 | public CompletableFuture provideCodeLenses(ICodeLensContext context, IProgressMonitor monitor) { 11 | return CompletableFuture.supplyAsync(() -> { 12 | return provideSyncCodeLenses(context, monitor); 13 | }); 14 | } 15 | 16 | @Override 17 | public CompletableFuture resolveCodeLens(ICodeLensContext context, ICodeLens codeLens, 18 | IProgressMonitor monitor) { 19 | return CompletableFuture.supplyAsync(() -> { 20 | return resolveSyncCodeLens(context, codeLens, monitor); 21 | }); 22 | } 23 | 24 | protected abstract ICodeLens[] provideSyncCodeLenses(ICodeLensContext context, IProgressMonitor monitor); 25 | 26 | protected abstract ICodeLens resolveSyncCodeLens(ICodeLensContext context, ICodeLens codeLens, 27 | IProgressMonitor monitor); 28 | } 29 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/codelens/CodeLens.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.codelens; 2 | 3 | public abstract class CodeLens implements ICodeLens { 4 | 5 | private Range range; 6 | private ICommand command; 7 | 8 | public CodeLens(int startLineNumber) { 9 | this(new Range(startLineNumber, 1)); 10 | } 11 | 12 | public CodeLens(Range range) { 13 | this.range = range; 14 | } 15 | 16 | @Override 17 | public Range getRange() { 18 | return range; 19 | } 20 | 21 | @Override 22 | public boolean isResolved() { 23 | return getCommand() != null; 24 | } 25 | 26 | @Override 27 | public ICommand getCommand() { 28 | return command; 29 | } 30 | 31 | public void setCommand(ICommand command) { 32 | this.command = command; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/codelens/CodeLensProviderRegistry.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.codelens; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import org.eclipse.codelens.internal.CodeLensPlugin; 9 | import org.eclipse.core.runtime.IConfigurationElement; 10 | import org.eclipse.core.runtime.IExtensionDelta; 11 | import org.eclipse.core.runtime.IExtensionRegistry; 12 | import org.eclipse.core.runtime.IRegistryChangeEvent; 13 | import org.eclipse.core.runtime.IRegistryChangeListener; 14 | import org.eclipse.core.runtime.Platform; 15 | 16 | public class CodeLensProviderRegistry implements IRegistryChangeListener { 17 | 18 | private static final CodeLensProviderRegistry INSTANCE = new CodeLensProviderRegistry(); 19 | private static final String EXTENSION_CODELENS_PROVIDERS = "codeLensProviders"; 20 | 21 | public static CodeLensProviderRegistry getInstance() { 22 | return INSTANCE; 23 | } 24 | 25 | private boolean codeLensProviderLoaded; 26 | private final Map> providersMap; 27 | 28 | public CodeLensProviderRegistry() { 29 | this.providersMap = new HashMap<>(); 30 | this.codeLensProviderLoaded = false; 31 | } 32 | 33 | public void register(String target, ICodeLensProvider provider) { 34 | List providers = providersMap.get(target); 35 | if (providers == null) { 36 | providers = new ArrayList<>(); 37 | providersMap.put(target, providers); 38 | } 39 | providers.add(provider); 40 | } 41 | 42 | public List all(String target) { 43 | loadCodeLensProvidersIfNeeded(); 44 | return providersMap.get(target); 45 | } 46 | 47 | @Override 48 | public void registryChanged(IRegistryChangeEvent event) { 49 | IExtensionDelta[] deltas = event.getExtensionDeltas(CodeLensPlugin.PLUGIN_ID, EXTENSION_CODELENS_PROVIDERS); 50 | if (deltas != null) { 51 | for (IExtensionDelta delta : deltas) 52 | handleCodeLensProvidersDelta(delta); 53 | } 54 | } 55 | 56 | private void loadCodeLensProvidersIfNeeded() { 57 | if (codeLensProviderLoaded) { 58 | return; 59 | } 60 | loadCodeLensProviders(); 61 | } 62 | 63 | /** 64 | * Load the SourceMap language supports. 65 | */ 66 | private synchronized void loadCodeLensProviders() { 67 | if (codeLensProviderLoaded) { 68 | return; 69 | } 70 | 71 | try { 72 | IExtensionRegistry registry = Platform.getExtensionRegistry(); 73 | if (registry == null) { 74 | return; 75 | } 76 | IConfigurationElement[] cf = registry.getConfigurationElementsFor(CodeLensPlugin.PLUGIN_ID, 77 | EXTENSION_CODELENS_PROVIDERS); 78 | loadCodeLensProvidersFromExtension(cf); 79 | } finally { 80 | codeLensProviderLoaded = true; 81 | } 82 | } 83 | 84 | /** 85 | * Add the SourceMap language supports. 86 | */ 87 | private synchronized void loadCodeLensProvidersFromExtension(IConfigurationElement[] cf) { 88 | for (IConfigurationElement ce : cf) { 89 | try { 90 | String target = ce.getAttribute("targetId"); 91 | ICodeLensProvider provider = (ICodeLensProvider) ce.createExecutableExtension("class"); 92 | register(target, provider); 93 | } catch (Throwable e) { 94 | CodeLensPlugin.log(e); 95 | } 96 | } 97 | } 98 | 99 | protected void handleCodeLensProvidersDelta(IExtensionDelta delta) { 100 | if (!codeLensProviderLoaded) // not loaded yet 101 | return; 102 | 103 | IConfigurationElement[] cf = delta.getExtension().getConfigurationElements(); 104 | 105 | // List list = new 106 | // ArrayList( 107 | // codeLensProviders); 108 | // if (delta.getKind() == IExtensionDelta.ADDED) { 109 | // loadCodeLensProvidersFromExtension(cf, list); 110 | // } else { 111 | // int size = list.size(); 112 | // CodeLensProviderType[] st = new CodeLensProviderType[size]; 113 | // list.toArray(st); 114 | // int size2 = cf.length; 115 | // 116 | // for (int i = 0; i < size; i++) { 117 | // for (int j = 0; j < size2; j++) { 118 | // if (st[i].getId().equals(cf[j].getAttribute("id"))) { 119 | // list.remove(st[i]); 120 | // } 121 | // } 122 | // } 123 | // } 124 | // codeLensProviders = list; 125 | } 126 | 127 | public void initialize() { 128 | IExtensionRegistry registry = Platform.getExtensionRegistry(); 129 | registry.addRegistryChangeListener(this, CodeLensPlugin.PLUGIN_ID); 130 | } 131 | 132 | public void destroy() { 133 | Platform.getExtensionRegistry().removeRegistryChangeListener(this); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/codelens/Command.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.codelens; 2 | 3 | public class Command implements ICommand { 4 | 5 | private final String title; 6 | private final String command; 7 | 8 | public Command(String title, String command) { 9 | this.title = title; 10 | this.command = command; 11 | } 12 | 13 | @Override 14 | public String getTitle() { 15 | return title; 16 | } 17 | 18 | @Override 19 | public String getCommand() { 20 | return command; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/codelens/DefaultCodeLensContext.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.codelens; 2 | 3 | import org.eclipse.jface.text.ITextViewer; 4 | 5 | public class DefaultCodeLensContext implements ICodeLensContext { 6 | 7 | private final ITextViewer textViewer; 8 | 9 | public DefaultCodeLensContext(ITextViewer textViewer) { 10 | this.textViewer = textViewer; 11 | } 12 | 13 | @Override 14 | public ITextViewer getViewer() { 15 | return textViewer; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/codelens/ICodeLens.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.codelens; 2 | 3 | /** 4 | * A code lens represents a command that should be shown along with source text, 5 | * like the number of references, a way to run tests, etc. 6 | * 7 | * A code lens is _unresolved_ when no command is associated to it. For 8 | * performance reasons the creation of a code lens and resolving should be done 9 | * in two stages. 10 | */ 11 | public interface ICodeLens { 12 | 13 | /** 14 | * The range in which this code lens is valid. Should only span a single 15 | * line. 16 | */ 17 | Range getRange(); 18 | 19 | /** 20 | * Returns `true` when there is a command associated. 21 | * @return `true` when there is a command associated. 22 | */ 23 | boolean isResolved(); 24 | 25 | /** 26 | * The command this code lens represents. 27 | */ 28 | ICommand getCommand(); 29 | 30 | void open(); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/codelens/ICodeLensContext.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.codelens; 2 | 3 | import org.eclipse.jface.text.ITextViewer; 4 | 5 | public interface ICodeLensContext { 6 | 7 | ITextViewer getViewer(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/codelens/ICodeLensProvider.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.codelens; 2 | 3 | import java.util.concurrent.CompletableFuture; 4 | 5 | import org.eclipse.core.runtime.IProgressMonitor; 6 | 7 | /** 8 | * A code lens provider adds [commands](#Command) to source text. The commands 9 | * will be shown as dedicated horizontal lines in between the source text. 10 | */ 11 | public interface ICodeLensProvider { 12 | 13 | /** 14 | * Compute a list of [lenses](#CodeLens). This call should return as fast as 15 | * possible and if computing the commands is expensive implementors should only 16 | * return code lens objects with the range set and implement 17 | * [resolve](#CodeLensProvider.resolveCodeLens). 18 | * 19 | * @param document 20 | * The document in which the command was invoked. 21 | * @param token 22 | * A cancellation token. 23 | * @return An array of code lenses or a thenable that resolves to such. The lack 24 | * of a result can be signaled by returning `undefined`, `null`, or an 25 | * empty array. 26 | */ 27 | CompletableFuture provideCodeLenses(ICodeLensContext context, IProgressMonitor monitor); 28 | 29 | /** 30 | * This function will be called for each visible code lens, usually when 31 | * scrolling and after calls to 32 | * [compute](#CodeLensProvider.provideCodeLenses)-lenses. 33 | * 34 | * @param codeLens 35 | * code lens that must be resolved. 36 | * @param token 37 | * A cancellation token. 38 | * @return The given, resolved code lens or thenable that resolves to such. 39 | */ 40 | CompletableFuture resolveCodeLens(ICodeLensContext context, ICodeLens codeLens, 41 | IProgressMonitor monitor); 42 | } 43 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/codelens/ICommand.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.codelens; 2 | 3 | /** 4 | * Represents a reference to a command. Provides a title which will be used to 5 | * represent a command in the UI and, optionally, an array of arguments which 6 | * will be passed to the command handler function when invoked. 7 | */ 8 | public interface ICommand { 9 | 10 | /** 11 | * Title of the command, like `save`. 12 | */ 13 | String getTitle(); 14 | 15 | /** 16 | * The identifier of the actual command handler. 17 | * 18 | * @see [commands.registerCommand](#commands.registerCommand). 19 | */ 20 | String getCommand(); 21 | 22 | /** 23 | * A tooltip for for command, when represented in the UI. 24 | */ 25 | default String getTooltip() { 26 | return null; 27 | } 28 | 29 | /** 30 | * Arguments that the command handler should be invoked with. 31 | */ 32 | default Object[] getArguments() { 33 | return null; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/codelens/Range.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.codelens; 2 | 3 | public class Range { 4 | 5 | /** 6 | * Line number on which the range starts (starts at 1). 7 | */ 8 | public final int startLineNumber; 9 | 10 | /** 11 | * Column on which the range starts in line `startLineNumber` (starts at 1). 12 | */ 13 | public final int startColumn; 14 | 15 | 16 | public Range(int startLineNumber, int startColumn) { 17 | this.startLineNumber = startLineNumber; 18 | this.startColumn = startColumn; 19 | } 20 | /** 21 | * Column on which the range starts in line `startLineNumber` (starts at 1). 22 | */ 23 | // readonly startColumn: number; 24 | /** 25 | * Line number on which the range ends. 26 | */ 27 | // readonly endLineNumber: number; 28 | /** 29 | * Column on which the range ends in line `endLineNumber`. 30 | */ 31 | // readonly endColumn: number; 32 | } 33 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/codelens/internal/CodeLens.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.codelens.internal; 2 | 3 | import java.util.List; 4 | 5 | import org.eclipse.jface.text.provisional.codelens.ICodeLens; 6 | import org.eclipse.jface.text.provisional.codelens.Range; 7 | import org.eclipse.jface.text.provisional.viewzones.ViewZoneChangeAccessor; 8 | 9 | public class CodeLens { 10 | 11 | private CodeLensViewZone zone; 12 | private List _data; 13 | 14 | public CodeLens(List data, CodeLensHelper helper, ViewZoneChangeAccessor accessor) { 15 | Range range = data.get(0).getSymbol().getRange(); 16 | zone = new CodeLensViewZone(range.startLineNumber - 1, 20); 17 | accessor.addZone(zone); 18 | _data = data; 19 | } 20 | 21 | public boolean isValid() { 22 | return zone != null && !zone.isDisposed(); 23 | } 24 | 25 | public void dispose(CodeLensHelper helper, ViewZoneChangeAccessor accessor) { 26 | accessor.removeZone(zone); 27 | } 28 | 29 | public int getLineNumber() { 30 | if (!isValid()) { 31 | return -1; 32 | } 33 | return zone.getAfterLineNumber() + 1; 34 | } 35 | 36 | public int getOffsetAtLine() { 37 | if (!isValid()) { 38 | return -1; 39 | } 40 | return zone.getOffsetAtLine(); 41 | } 42 | 43 | public void updateCodeLensSymbols(List data, CodeLensHelper helper) { 44 | this._data = data; 45 | } 46 | 47 | public List computeIfNecessary(Object object) { 48 | return this._data; 49 | } 50 | 51 | public void updateCommands(List resolvedSymbols) { 52 | zone.updateCommands(resolvedSymbols); 53 | } 54 | 55 | public void redraw(ViewZoneChangeAccessor accessor) { 56 | accessor.layoutZone(zone); 57 | } 58 | 59 | public Integer getTopMargin() { 60 | if (isValid() && zone.getAfterLineNumber() == 0) { 61 | return zone.getHeightInPx(); 62 | } 63 | return null; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/codelens/internal/CodeLensData.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.codelens.internal; 2 | 3 | import org.eclipse.jface.text.provisional.codelens.ICodeLensProvider; 4 | import org.eclipse.jface.text.provisional.codelens.ICodeLens; 5 | 6 | public class CodeLensData { 7 | 8 | private final ICodeLens symbol; 9 | private final ICodeLensProvider provider; 10 | 11 | public CodeLensData(ICodeLens symbol, ICodeLensProvider provider) { 12 | this.symbol = symbol; 13 | this.provider = provider; 14 | } 15 | 16 | public ICodeLens getSymbol() { 17 | return symbol; 18 | } 19 | 20 | public ICodeLensProvider getProvider() { 21 | return provider; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/codelens/internal/CodeLensHelper.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.codelens.internal; 2 | 3 | public class CodeLensHelper { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/codelens/internal/CodeLensViewZone.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.codelens.internal; 2 | 3 | import java.util.List; 4 | 5 | import org.eclipse.jface.text.BadLocationException; 6 | import org.eclipse.jface.text.IDocument; 7 | import org.eclipse.jface.text.provisional.codelens.ICodeLens; 8 | import org.eclipse.jface.text.provisional.viewzones.ViewZone; 9 | import org.eclipse.swt.SWT; 10 | import org.eclipse.swt.custom.StyledText; 11 | import org.eclipse.swt.events.MouseEvent; 12 | import org.eclipse.swt.graphics.Font; 13 | import org.eclipse.swt.graphics.GC; 14 | import org.eclipse.swt.graphics.Point; 15 | import org.eclipse.swt.graphics.Rectangle; 16 | 17 | public class CodeLensViewZone extends ViewZone { 18 | 19 | private MouseEvent hover; 20 | private List resolvedSymbols; 21 | private ICodeLens hoveredCodeLens; 22 | private Integer hoveredCodeLensStartX; 23 | private Integer hoveredCodeLensEndX; 24 | 25 | public CodeLensViewZone(int afterLineNumber, int height) { 26 | super(afterLineNumber, height); 27 | } 28 | 29 | @Override 30 | public void mouseHover(MouseEvent event) { 31 | hover = event; 32 | StyledText styledText = getTextViewer().getTextWidget(); 33 | styledText.setCursor(styledText.getDisplay().getSystemCursor(SWT.CURSOR_HAND)); 34 | 35 | } 36 | 37 | @Override 38 | public void mouseEnter(MouseEvent event) { 39 | hover = event; 40 | StyledText styledText = getTextViewer().getTextWidget(); 41 | styledText.setCursor(styledText.getDisplay().getSystemCursor(SWT.CURSOR_HAND)); 42 | } 43 | 44 | @Override 45 | public void mouseExit(MouseEvent event) { 46 | hover = null; 47 | StyledText styledText = getTextViewer().getTextWidget(); 48 | styledText.setCursor(null); 49 | } 50 | 51 | public MouseEvent getHover() { 52 | return hover; 53 | } 54 | 55 | @Override 56 | public void onMouseClick(MouseEvent event) { 57 | if (hoveredCodeLens != null) { 58 | hoveredCodeLens.open(); 59 | } 60 | } 61 | 62 | public void updateCommands(List resolvedSymbols) { 63 | this.resolvedSymbols = resolvedSymbols; 64 | } 65 | 66 | @Override 67 | public void draw(int paintX, int paintSpaceLeadingX, int paintY, GC gc) { 68 | StyledText styledText = getTextViewer().getTextWidget(); 69 | Rectangle client = styledText.getClientArea(); 70 | gc.setBackground(styledText.getDisplay().getSystemColor(SWT.COLOR_WHITE)); 71 | styledText.drawBackground(gc, paintX, paintY, client.width, this.getHeightInPx()); 72 | 73 | gc.setForeground(styledText.getDisplay().getSystemColor(SWT.COLOR_GRAY)); 74 | 75 | Font font = new Font(styledText.getDisplay(), "Arial", 9, SWT.ITALIC); 76 | gc.setFont(font); 77 | String text = getText(gc, paintSpaceLeadingX); 78 | if (text != null) { 79 | int y = paintY + 4; 80 | gc.drawText(text, paintSpaceLeadingX, y); 81 | 82 | if (hoveredCodeLensEndX != null) { 83 | Point extent = gc.textExtent(text); 84 | gc.drawLine(hoveredCodeLensStartX, y + extent.y - 1, hoveredCodeLensEndX, y + extent.y - 1); 85 | } 86 | } 87 | } 88 | 89 | public String getText(GC gc, int x) { 90 | hoveredCodeLens = null; 91 | hoveredCodeLensStartX = null; 92 | hoveredCodeLensEndX = null; 93 | if (resolvedSymbols == null || resolvedSymbols.size() < 1) { 94 | return "no command"; 95 | } else { 96 | StringBuilder text = new StringBuilder(); 97 | int i = 0; 98 | boolean hasHover = hover != null; 99 | for (ICodeLens codeLens : resolvedSymbols) { 100 | if (i > 0) { 101 | text.append(" | "); 102 | } 103 | Integer startX = null; 104 | if (hasHover && hoveredCodeLens == null) { 105 | startX = gc.textExtent(text.toString()).x + x; 106 | } 107 | text.append(codeLens.getCommand().getTitle()); 108 | if (hasHover && hoveredCodeLens == null) { 109 | int endX = gc.textExtent(text.toString()).x + x; 110 | if (hover.x < endX) { 111 | hoveredCodeLensStartX = startX; 112 | hoveredCodeLensEndX = endX; 113 | hoveredCodeLens = codeLens; 114 | } 115 | } 116 | i++; 117 | } 118 | return text.toString(); 119 | } 120 | } 121 | 122 | @Override 123 | protected int getOffsetAtLine(int lineIndex) { 124 | IDocument document = getTextViewer().getDocument(); 125 | try { 126 | int lo = document.getLineOffset(lineIndex); 127 | int ll = document.getLineLength(lineIndex); 128 | String line = document.get(lo, ll); 129 | return super.getOffsetAtLine(lineIndex) + getLeadingSpaces(line); 130 | } catch (BadLocationException e) { 131 | return -1; 132 | } 133 | } 134 | 135 | private static int getLeadingSpaces(String line) { 136 | int counter = 0; 137 | 138 | char[] chars = line.toCharArray(); 139 | for (char c : chars) { 140 | if (c == '\t') 141 | counter++; 142 | else if (c == ' ') 143 | counter++; 144 | else 145 | break; 146 | } 147 | 148 | return counter; 149 | } 150 | 151 | @Override 152 | public void dispose() { 153 | if (!isDisposed()) { 154 | StyledText styledText = getTextViewer().getTextWidget(); 155 | styledText.getDisplay().syncExec(() -> styledText.setCursor(null)); 156 | } 157 | super.dispose(); 158 | } 159 | 160 | } -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/viewzones/DefaultViewZone.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.viewzones; 2 | 3 | import org.eclipse.swt.SWT; 4 | import org.eclipse.swt.custom.StyledText; 5 | import org.eclipse.swt.graphics.Font; 6 | import org.eclipse.swt.graphics.GC; 7 | import org.eclipse.swt.graphics.Rectangle; 8 | 9 | public class DefaultViewZone extends ViewZone { 10 | 11 | private String text; 12 | 13 | public DefaultViewZone(int afterLineNumber, int height) { 14 | super(afterLineNumber, height); 15 | } 16 | 17 | public DefaultViewZone(int afterLineNumber, int height, String text) { 18 | this(afterLineNumber, height); 19 | setText(text); 20 | } 21 | 22 | public void setText(String text) { 23 | this.text = text; 24 | } 25 | 26 | public String getText() { 27 | return text; 28 | } 29 | 30 | @Override 31 | public void draw(int paintX, int paintSpaceLeadingX, int paintY, GC gc) { 32 | StyledText styledText = super.getTextViewer().getTextWidget(); 33 | Rectangle client = styledText.getClientArea(); 34 | gc.setBackground(styledText.getDisplay().getSystemColor(SWT.COLOR_WHITE)); 35 | styledText.drawBackground(gc, paintX, paintY, client.width, super.getHeightInPx()); 36 | gc.setForeground(styledText.getDisplay().getSystemColor(SWT.COLOR_GRAY)); 37 | 38 | Font font = new Font(styledText.getDisplay(), "Arial", 9, SWT.ITALIC); 39 | gc.setFont(font); 40 | gc.drawText(this.getText(), paintX, paintY + 4); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/viewzones/IViewZone.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.viewzones; 2 | 3 | import org.eclipse.jface.text.ITextViewer; 4 | import org.eclipse.swt.events.MouseEvent; 5 | import org.eclipse.swt.graphics.GC; 6 | 7 | public interface IViewZone { 8 | 9 | /** 10 | * The line number after which this zone should appear. Use 0 to place a 11 | * view zone before the first line number. 12 | */ 13 | int getAfterLineNumber(); 14 | 15 | int getOffsetAtLine(); 16 | 17 | void setOffsetAtLine(int offsetAtLine); 18 | 19 | int getHeightInPx(); 20 | 21 | void setTextViewer(ITextViewer textViewer); 22 | 23 | boolean isDisposed(); 24 | 25 | void dispose(); 26 | 27 | void mouseHover(MouseEvent event); 28 | 29 | void mouseExit(MouseEvent event); 30 | 31 | void mouseEnter(MouseEvent event); 32 | 33 | void onMouseClick(MouseEvent event); 34 | 35 | void draw(int paintX, int paintSpaceLeadingX, int paintY, GC gc); 36 | } 37 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/viewzones/IViewZoneChangeAccessor.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.viewzones; 2 | 3 | /** 4 | * An accessor that allows for zones to be added or removed. 5 | */ 6 | public interface IViewZoneChangeAccessor { 7 | 8 | /** 9 | * Create a new view zone. 10 | * 11 | * @param zone 12 | * Zone to create 13 | */ 14 | void addZone(IViewZone zone); 15 | 16 | /** 17 | * Remove a zone 18 | * 19 | * @param zone 20 | */ 21 | void removeZone(IViewZone zone); 22 | 23 | /** 24 | * Change a zone's position. The editor will rescan the `afterLineNumber` 25 | * and `afterColumn` properties of a view zone. 26 | */ 27 | void layoutZone(IViewZone zone); 28 | 29 | /** 30 | * Returns number of zones. 31 | * 32 | * @return number of zones. 33 | */ 34 | int getSize(); 35 | } -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/viewzones/ViewZone.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.viewzones; 2 | 3 | import org.eclipse.jface.text.BadLocationException; 4 | import org.eclipse.jface.text.ITextViewer; 5 | import org.eclipse.swt.custom.StyledText; 6 | import org.eclipse.swt.events.MouseEvent; 7 | 8 | public abstract class ViewZone implements IViewZone { 9 | 10 | private ITextViewer textViewer; 11 | private int offsetAtLine; 12 | private int afterLineNumber; 13 | private int height; 14 | 15 | private boolean disposed; 16 | 17 | public ViewZone(int afterLineNumber, int height) { 18 | this.height = height; 19 | setAfterLineNumber(afterLineNumber); 20 | } 21 | 22 | public void setTextViewer(ITextViewer textViewer) { 23 | this.textViewer = textViewer; 24 | } 25 | 26 | public void setAfterLineNumber(int afterLineNumber) { 27 | this.afterLineNumber = afterLineNumber; 28 | this.offsetAtLine = -1; 29 | } 30 | 31 | @Override 32 | public int getAfterLineNumber() { 33 | if (offsetAtLine != -1) { 34 | try { 35 | StyledText styledText = textViewer.getTextWidget(); 36 | afterLineNumber = textViewer.getDocument().getLineOfOffset(offsetAtLine); //styledText.getLineAtOffset(offsetAtLine); 37 | } catch (Exception e) { 38 | // e.printStackTrace(); 39 | return -1; 40 | } 41 | } 42 | return afterLineNumber; 43 | } 44 | 45 | public int getOffsetAtLine() { 46 | if (offsetAtLine == -1) { 47 | offsetAtLine = getOffsetAtLine(afterLineNumber); 48 | } 49 | return offsetAtLine; 50 | } 51 | 52 | protected int getOffsetAtLine(int lineIndex) { 53 | try { 54 | return textViewer.getDocument().getLineOffset(lineIndex); 55 | } catch (BadLocationException e) { 56 | return -1; 57 | } 58 | //StyledText styledText = textViewer.getTextWidget(); 59 | //return styledText.getOffsetAtLine(lineIndex); 60 | } 61 | 62 | public void setOffsetAtLine(int offsetAtLine) { 63 | this.afterLineNumber = -1; 64 | this.offsetAtLine = offsetAtLine; 65 | } 66 | 67 | @Override 68 | public int getHeightInPx() { 69 | return height; 70 | } 71 | 72 | @Override 73 | public void dispose() { 74 | this.disposed = true; 75 | this.setTextViewer(null); 76 | } 77 | 78 | @Override 79 | public boolean isDisposed() { 80 | return disposed; 81 | } 82 | 83 | @Override 84 | public void mouseHover(MouseEvent event) { 85 | // System.err.println("mouseHover");tt 86 | } 87 | 88 | @Override 89 | public void mouseEnter(MouseEvent event) { 90 | // System.err.println("mouseEnter"); 91 | } 92 | 93 | @Override 94 | public void mouseExit(MouseEvent event) { 95 | // System.err.println("mouseExit"); 96 | } 97 | 98 | @Override 99 | public void onMouseClick(MouseEvent event) { 100 | 101 | } 102 | 103 | // public StyledText getStyledText() { 104 | // return styledText; 105 | // } 106 | 107 | public ITextViewer getTextViewer() { 108 | return textViewer; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/provisional/viewzones/ViewZoneChangeAccessor.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.provisional.viewzones; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.eclipse.jface.text.DocumentEvent; 7 | import org.eclipse.jface.text.IDocument; 8 | import org.eclipse.jface.text.IDocumentListener; 9 | import org.eclipse.jface.text.IPaintPositionManager; 10 | import org.eclipse.jface.text.IPainter; 11 | import org.eclipse.jface.text.ITextViewer; 12 | import org.eclipse.jface.text.ITextViewerExtension2; 13 | import org.eclipse.jface.text.JFaceTextUtil; 14 | import org.eclipse.swt.custom.StyledText; 15 | import org.eclipse.swt.custom.patch.StyledTextPatcher; 16 | import org.eclipse.swt.custom.provisional.ILineSpacingProvider; 17 | import org.eclipse.swt.events.MouseEvent; 18 | import org.eclipse.swt.events.MouseListener; 19 | import org.eclipse.swt.events.MouseMoveListener; 20 | import org.eclipse.swt.events.PaintEvent; 21 | import org.eclipse.swt.events.PaintListener; 22 | import org.eclipse.swt.graphics.Color; 23 | import org.eclipse.swt.graphics.GC; 24 | import org.eclipse.swt.graphics.Point; 25 | 26 | public class ViewZoneChangeAccessor implements IViewZoneChangeAccessor, ILineSpacingProvider, IPainter, PaintListener { 27 | 28 | private final ITextViewer textViewer; 29 | private List viewZones; 30 | 31 | /** The active state of this painter */ 32 | private boolean fIsActive = false; 33 | private StyledText fTextWidget; 34 | private int originalTopMargin; 35 | private ViewZoneMouseListener mouseListener; 36 | 37 | private class ViewZoneMouseListener implements MouseListener, MouseMoveListener { 38 | 39 | private IViewZone hoveredZone; 40 | 41 | @Override 42 | public void mouseUp(MouseEvent event) { 43 | } 44 | 45 | @Override 46 | public void mouseDown(MouseEvent event) { 47 | if (hoveredZone != null && hoveredZone.isDisposed()) { 48 | hoveredZone = null; 49 | } 50 | if (event.button == 1 && hoveredZone != null) { 51 | hoveredZone.onMouseClick(event); 52 | } 53 | } 54 | 55 | @Override 56 | public void mouseDoubleClick(MouseEvent event) { 57 | 58 | } 59 | 60 | @Override 61 | public void mouseMove(MouseEvent event) { 62 | int lineIndex = fTextWidget.getLineIndex(event.y); 63 | int lineNumber = lineIndex + 1; 64 | IViewZone zone = getViewZone(lineNumber); 65 | if (zone != null) { 66 | // The line which have a zone at end of this line is 67 | // hovered. 68 | // Check if it's the zone which is hovered or the view zone. 69 | int offset = fTextWidget.getOffsetAtLine(lineIndex + 1); 70 | Point p = fTextWidget.getLocationAtOffset(offset); 71 | if (p.y - zone.getHeightInPx() < event.y) { 72 | // Zone is hovered 73 | if (zone.equals(hoveredZone)) { 74 | hoveredZone.mouseHover(event); 75 | layoutZone(hoveredZone); 76 | } else { 77 | if (hoveredZone != null) { 78 | hoveredZone.mouseExit(event); 79 | layoutZone(hoveredZone); 80 | } 81 | hoveredZone = zone; 82 | hoveredZone.mouseEnter(event); 83 | layoutZone(hoveredZone); 84 | } 85 | } else { 86 | if (hoveredZone != null) { 87 | hoveredZone.mouseExit(event); 88 | layoutZone(hoveredZone); 89 | hoveredZone = null; 90 | } 91 | } 92 | } else if (hoveredZone != null) { 93 | if (!hoveredZone.isDisposed()) { 94 | hoveredZone.mouseExit(event); 95 | layoutZone(hoveredZone); 96 | } 97 | hoveredZone = null; 98 | } 99 | } 100 | } 101 | 102 | public ViewZoneChangeAccessor(ITextViewer textViewer) { 103 | super(); 104 | this.textViewer = textViewer; 105 | fTextWidget = textViewer.getTextWidget(); 106 | originalTopMargin = fTextWidget.getTopMargin(); 107 | this.viewZones = new ArrayList<>(); 108 | try { 109 | // Should be replaced with 110 | // "fTextWidget.setLineSpacingProvider(this);" 111 | StyledTextPatcher.setLineSpacingProvider(fTextWidget, this); 112 | } catch (Exception e) { 113 | e.printStackTrace(); 114 | } 115 | // synch(fTextWidget); 116 | 117 | textViewer.getDocument().addDocumentListener(new IDocumentListener() { 118 | 119 | private List toUpdate = new ArrayList<>(); 120 | 121 | @Override 122 | public void documentChanged(DocumentEvent event) { 123 | if (!toUpdate.isEmpty()) { 124 | textViewer.getTextWidget().getDisplay().asyncExec(() -> { 125 | for (IViewZone viewZone : toUpdate) { 126 | ViewZoneChangeAccessor.this.layoutZone(viewZone); 127 | } 128 | }); 129 | } 130 | } 131 | 132 | @Override 133 | public void documentAboutToBeChanged(DocumentEvent e) { 134 | int start = e.getOffset(); 135 | int replaceCharCount = e.getLength(); 136 | int newCharCount = e.getText().length(); 137 | synchronized (viewZones) { 138 | toUpdate.clear(); 139 | List toRemove = new ArrayList<>(); 140 | for (IViewZone viewZone : viewZones) { 141 | // System.err.println("before:" + 142 | // viewZone.getAfterLineNumber()); 143 | int oldOffset = viewZone.getOffsetAtLine(); 144 | int newOffset = oldOffset; 145 | if (start <= newOffset && newOffset < start + replaceCharCount) { 146 | // this zone is being deleted from the text 147 | toRemove.add(viewZone); 148 | newOffset = -1; 149 | } 150 | if (newOffset != -1 && newOffset >= start) { 151 | newOffset += newCharCount - replaceCharCount; 152 | } 153 | if (oldOffset != newOffset) { 154 | viewZone.setOffsetAtLine(newOffset); 155 | toUpdate.add(viewZone); 156 | } 157 | // System.err.println("after:" + 158 | // viewZone.getAfterLineNumber()); 159 | } 160 | 161 | for (IViewZone viewZone : toRemove) { 162 | removeZone(viewZone); 163 | } 164 | } 165 | 166 | } 167 | }); 168 | 169 | mouseListener = new ViewZoneMouseListener(); 170 | textViewer.getTextWidget().addMouseMoveListener(mouseListener); 171 | textViewer.getTextWidget().addMouseListener(mouseListener); 172 | ((ITextViewerExtension2) textViewer).addPainter(this); 173 | } 174 | 175 | @Override 176 | public void addZone(IViewZone zone) { 177 | synchronized (viewZones) { 178 | viewZones.add(zone); 179 | zone.setTextViewer(textViewer); 180 | } 181 | } 182 | 183 | @Override 184 | public void removeZone(IViewZone zone) { 185 | synchronized (viewZones) { 186 | viewZones.remove(zone); 187 | zone.dispose(); 188 | } 189 | } 190 | 191 | @Override 192 | public void layoutZone(IViewZone zone) { 193 | StyledText styledText = textViewer.getTextWidget(); 194 | int line = zone.getAfterLineNumber(); 195 | if (line == 0) { 196 | styledText.setTopMargin(zone.isDisposed() ? originalTopMargin : zone.getHeightInPx()); 197 | } else { 198 | line--; 199 | int start = styledText.getOffsetAtLine(line); 200 | int length = styledText.getText().length() - start; 201 | styledText.redrawRange(start, length, true); 202 | } 203 | } 204 | 205 | public IViewZone getViewZone(int lineNumber) { 206 | synchronized (viewZones) { 207 | for (IViewZone viewZone : viewZones) { 208 | if (lineNumber == viewZone.getAfterLineNumber()) { 209 | return viewZone; 210 | } 211 | } 212 | } 213 | return null; 214 | } 215 | 216 | @Override 217 | public int getSize() { 218 | return viewZones.size(); 219 | } 220 | 221 | @Override 222 | public Integer getLineSpacing(int widgetLine) { 223 | int lineNumber = getLineNumber(widgetLine); 224 | IViewZone viewZone = getViewZone(lineNumber); 225 | if (viewZone != null) { 226 | // There is view zone to render for the given line, update the line 227 | // spacing of the TextLayout linked to this line number. 228 | return viewZone.getHeightInPx(); 229 | } 230 | return null; 231 | } 232 | 233 | private int getLineNumber(int widgetLine) { 234 | return JFaceTextUtil.widgetLine2ModelLine(textViewer, widgetLine) + 1; 235 | } 236 | 237 | @Override 238 | public void dispose() { 239 | fTextWidget.removeMouseMoveListener(mouseListener); 240 | fTextWidget.removeMouseListener(mouseListener); 241 | fTextWidget = null; 242 | } 243 | 244 | @Override 245 | public void paint(int reason) { 246 | IDocument document = textViewer.getDocument(); 247 | if (document == null) { 248 | deactivate(false); 249 | return; 250 | } 251 | if (!fIsActive) { 252 | StyledText styledText = textViewer.getTextWidget(); 253 | fIsActive = true; 254 | styledText.addPaintListener(this); 255 | redrawAll(); 256 | } else if (reason == CONFIGURATION || reason == INTERNAL) { 257 | redrawAll(); 258 | } 259 | } 260 | 261 | @Override 262 | public void deactivate(boolean redraw) { 263 | if (fIsActive) { 264 | fIsActive = false; 265 | fTextWidget.removePaintListener(this); 266 | if (redraw) { 267 | redrawAll(); 268 | } 269 | } 270 | } 271 | 272 | @Override 273 | public void setPositionManager(IPaintPositionManager manager) { 274 | 275 | } 276 | 277 | /** 278 | * Redraw all of the text widgets visible content. 279 | */ 280 | private void redrawAll() { 281 | // fTextWidget.redraw(); 282 | } 283 | 284 | @Override 285 | public void paintControl(PaintEvent event) { 286 | if (fTextWidget == null) 287 | return; 288 | if (event.width == 0 || event.height == 0) 289 | return; 290 | int clientAreaWidth = fTextWidget.getClientArea().width; 291 | int clientAreaHeight = fTextWidget.getClientArea().height; 292 | if (clientAreaWidth == 0 || clientAreaHeight == 0) 293 | return; 294 | 295 | int startLine = fTextWidget.getLineIndex(event.y); 296 | int y = startLine == 0 ? 0 : fTextWidget.getLinePixel(startLine); 297 | int endY = event.y + event.height; 298 | GC gc = event.gc; 299 | Color background = fTextWidget.getBackground(); 300 | Color foreground = fTextWidget.getForeground(); 301 | if (endY > 0) { 302 | int lineCount = fTextWidget.getLineCount(); 303 | int x = fTextWidget.getLeftMargin() - fTextWidget.getHorizontalPixel(); 304 | // leftMargin - horizontalScrollOffset; 305 | for (int lineIndex = startLine - 1; y < endY && lineIndex < lineCount; lineIndex++) { 306 | if (lineIndex == 0) { 307 | IViewZone viewZone = getViewZone(lineIndex); 308 | if (viewZone != null) { 309 | int height = viewZone.getHeightInPx() + originalTopMargin; 310 | // if (height != fTextWidget.getTopMargin()) { 311 | // fTextWidget.setTopMargin(height); 312 | // } 313 | // TODO: support codelens with changed of top margin 314 | // viewZone.getRenderer().draw(viewZone, x, 0, gc, 315 | // fTextWidget); 316 | } else { 317 | // if (originalTopMargin != fTextWidget.getTopMargin()) 318 | // { 319 | // fTextWidget.setTopMargin(originalTopMargin); 320 | // } 321 | } 322 | } 323 | int lineNumber = getLineNumber(lineIndex) - 1; 324 | IViewZone viewZone = getViewZone(lineNumber); 325 | if (viewZone != null) { 326 | int offset = fTextWidget.getOffsetAtLine(lineIndex) 327 | + getLeadingSpaces(fTextWidget.getLine(lineIndex)); 328 | // JFaceTextUtil.modelLineToWidgetLine(viewer, modelLine) 329 | Point topLeft = fTextWidget.getLocationAtOffset(offset); 330 | y = topLeft.y; // fTextWidget.getLinePixel(lineIndex); 331 | viewZone.draw(x, topLeft.x, y - viewZone.getHeightInPx(), gc); 332 | } 333 | } 334 | } 335 | } 336 | 337 | private static int getLeadingSpaces(String line) { 338 | int counter = 0; 339 | 340 | char[] chars = line.toCharArray(); 341 | for (char c : chars) { 342 | if (c == '\t') 343 | counter++; 344 | else if (c == ' ') 345 | counter++; 346 | else 347 | break; 348 | } 349 | 350 | return counter; 351 | } 352 | } 353 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/jface/text/source/patch/LineNumberChangeRulerColumnPatch.java: -------------------------------------------------------------------------------- 1 | package org.eclipse.jface.text.source.patch; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.Method; 5 | 6 | import org.eclipse.jface.internal.text.revisions.RevisionPainter; 7 | import org.eclipse.jface.internal.text.source.DiffPainter; 8 | import org.eclipse.jface.text.ITextViewer; 9 | import org.eclipse.jface.text.JFaceTextUtil; 10 | import org.eclipse.jface.text.source.CompositeRuler; 11 | import org.eclipse.jface.text.source.ILineRange; 12 | import org.eclipse.jface.text.source.ISharedTextColors; 13 | import org.eclipse.jface.text.source.LineNumberChangeRulerColumn; 14 | import org.eclipse.jface.text.source.LineNumberRulerColumn; 15 | import org.eclipse.swt.custom.StyledText; 16 | import org.eclipse.swt.graphics.Color; 17 | import org.eclipse.swt.graphics.GC; 18 | import org.eclipse.swt.widgets.Display; 19 | 20 | import javassist.util.proxy.MethodHandler; 21 | import javassist.util.proxy.ProxyFactory; 22 | 23 | public class LineNumberChangeRulerColumnPatch { 24 | 25 | public static LineNumberChangeRulerColumn create(ISharedTextColors sharedColors) { 26 | try { 27 | ProxyFactory factory = new ProxyFactory(); 28 | factory.setSuperclass(LineNumberChangeRulerColumn.class); 29 | factory.setHandler(new LineNumberChangeRulerColumnMethodHandler()); 30 | return (LineNumberChangeRulerColumn) factory.create(new Class[] { ISharedTextColors.class }, 31 | new Object[] { sharedColors }); 32 | } catch (Exception e) { 33 | e.printStackTrace(); 34 | return new LineNumberChangeRulerColumn(sharedColors); 35 | } 36 | } 37 | 38 | private static class LineNumberChangeRulerColumnMethodHandler implements MethodHandler { 39 | 40 | private ITextViewer fCachedTextViewer; 41 | private StyledText fCachedTextWidget; 42 | private boolean fCharacterDisplay; 43 | 44 | private RevisionPainter fRevisionPainter; 45 | /** 46 | * The diff information painter strategy. 47 | * 48 | * @since 3.2 49 | */ 50 | private DiffPainter fDiffPainter; 51 | 52 | @Override 53 | public Object invoke(Object obj, Method thisMethod, Method proceed, Object[] args) throws Throwable { 54 | if ("createControl".equals(thisMethod.getName())) { 55 | CompositeRuler parentRuler = (CompositeRuler) args[0]; 56 | this.fCachedTextViewer = parentRuler.getTextViewer(); 57 | this.fCachedTextWidget = fCachedTextViewer.getTextWidget(); 58 | } else if ("setDisplayMode".equals(thisMethod.getName())) { 59 | this.fCharacterDisplay = (boolean) args[0]; 60 | } else if ("doPaint".equals(thisMethod.getName()) && args.length > 1) { 61 | GC gc = (GC) args[0]; 62 | ILineRange visibleLines = (ILineRange) args[1]; 63 | 64 | if (fRevisionPainter == null) { 65 | fRevisionPainter = getValue("fRevisionPainter", obj); 66 | fDiffPainter = getValue("fDiffPainter", obj); 67 | } 68 | 69 | LineNumberChangeRulerColumn l = ((LineNumberChangeRulerColumn) obj); 70 | doPaint(gc, visibleLines, l); 71 | return null; 72 | } 73 | return proceed.invoke(obj, args); 74 | } 75 | 76 | void doPaint(GC gc, ILineRange visibleLines, LineNumberChangeRulerColumn l) { 77 | Color foreground = gc.getForeground(); 78 | if (visibleLines != null) { 79 | if (fRevisionPainter.hasInformation()) 80 | fRevisionPainter.paint(gc, visibleLines); 81 | else if (fDiffPainter.hasInformation()) // don't paint quick 82 | // diff 83 | // colors if revisions 84 | // are 85 | // painted 86 | fDiffPainter.paint(gc, visibleLines); 87 | } 88 | gc.setForeground(foreground); 89 | if (l.isShowingLineNumbers() || fCharacterDisplay) 90 | doPaintPatch(gc, visibleLines, l); 91 | } 92 | 93 | /** 94 | * Draws the ruler column. 95 | * 96 | * @param gc 97 | * the GC to draw into 98 | * @param visibleLines 99 | * the visible model lines 100 | * @since 3.2 101 | */ 102 | void doPaintPatch(GC gc, ILineRange visibleLines, LineNumberChangeRulerColumn l) { 103 | Display display = fCachedTextWidget.getDisplay(); 104 | 105 | // draw diff info 106 | int y = -JFaceTextUtil.getHiddenTopLinePixels(fCachedTextWidget); 107 | 108 | // add empty lines if line is wrapped 109 | boolean isWrapActive = fCachedTextWidget.getWordWrap(); 110 | 111 | int lastLine = end(visibleLines); 112 | for (int line = visibleLines.getStartLine(); line < lastLine; line++) { 113 | int widgetLine = JFaceTextUtil.modelLineToWidgetLine(fCachedTextViewer, line); 114 | if (widgetLine == -1) 115 | continue; 116 | 117 | final int offsetAtLine = fCachedTextWidget.getOffsetAtLine(widgetLine); 118 | // START PATCH 119 | // int lineHeight= 120 | // fCachedTextWidget.getLineHeight(offsetAtLine); 121 | int lineHeight = JFaceTextUtil.computeLineHeight(fCachedTextWidget, widgetLine, widgetLine + 1, 1); 122 | // END PATCH 123 | paintLine(line, y, lineHeight, gc, display, l); 124 | 125 | // increment y position 126 | if (!isWrapActive) { 127 | y += lineHeight; 128 | } else { 129 | int charCount = fCachedTextWidget.getCharCount(); 130 | if (offsetAtLine == charCount) 131 | continue; 132 | 133 | // end of wrapped line 134 | final int offsetEnd = offsetAtLine + fCachedTextWidget.getLine(widgetLine).length(); 135 | 136 | if (offsetEnd == charCount) 137 | continue; 138 | 139 | // use height of text bounding because bounds.width changes 140 | // on 141 | // word wrap 142 | y += fCachedTextWidget.getTextBounds(offsetAtLine, offsetEnd).height; 143 | } 144 | } 145 | } 146 | 147 | /* @since 3.2 */ 148 | private static int end(ILineRange range) { 149 | return range.getStartLine() + range.getNumberOfLines(); 150 | } 151 | 152 | }; 153 | 154 | private static T getValue(String name, Object instance) { 155 | try { 156 | Field f = LineNumberChangeRulerColumn.class.getDeclaredField(name); 157 | f.setAccessible(true); 158 | return (T) f.get(instance); 159 | } catch (Exception e) { 160 | e.printStackTrace(); 161 | return null; 162 | } 163 | } 164 | 165 | private static void paintLine(int line, int y, int lineHeight, GC gc, Display display, 166 | LineNumberChangeRulerColumn l) { 167 | try { 168 | Method m = LineNumberRulerColumn.class 169 | .getDeclaredMethod("paintLine", 170 | new Class[] { int.class, int.class, int.class, GC.class, Display.class }); 171 | m.setAccessible(true); 172 | m.invoke(l, line, y, lineHeight, gc, display); 173 | } catch (Exception e) { 174 | e.printStackTrace(); 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/swt/custom/patch/StyledTextPatcher.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-2017 Angelo ZERR. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * Angelo Zerr - initial API and implementation 10 | */ 11 | package org.eclipse.swt.custom.patch; 12 | 13 | import java.lang.reflect.Field; 14 | import java.lang.reflect.InvocationTargetException; 15 | import java.lang.reflect.Method; 16 | 17 | import org.eclipse.swt.custom.StyledText; 18 | import org.eclipse.swt.custom.StyledTextContent; 19 | import org.eclipse.swt.custom.provisional.ILineSpacingProvider; 20 | import org.eclipse.swt.graphics.Device; 21 | import org.eclipse.swt.graphics.Font; 22 | 23 | import javassist.util.proxy.ProxyFactory; 24 | 25 | public class StyledTextPatcher { 26 | 27 | private static Field RENDERER_FIELD; 28 | 29 | public static void setVariableLineHeight(StyledText styledText) { 30 | try { 31 | Method m1 = styledText.getClass().getDeclaredMethod("setVariableLineHeight"); 32 | m1.setAccessible(true); 33 | m1.invoke(styledText); 34 | } catch (Exception e) { 35 | e.printStackTrace(); 36 | } 37 | } 38 | 39 | public static void resetCache(StyledText styledText, int firstLine, int count) { 40 | try { 41 | Method m1 = styledText.getClass().getDeclaredMethod("resetCache", int.class, int.class); 42 | m1.setAccessible(true); 43 | m1.invoke(styledText, firstLine, count); 44 | } catch (Exception e) { 45 | e.printStackTrace(); 46 | } 47 | } 48 | 49 | public static void setCaretLocation(StyledText styledText) { 50 | try { 51 | Method m1 = styledText.getClass().getDeclaredMethod("setCaretLocation"); 52 | m1.setAccessible(true); 53 | m1.invoke(styledText); 54 | } catch (Exception e) { 55 | e.printStackTrace(); 56 | } 57 | } 58 | 59 | /** 60 | * This method should be replaced with 61 | * StyledText#setLineSpacingProvider(ILineSpacingProvider lineSpacingProvider); 62 | * 63 | * @param styledText 64 | * @param lineSpacingProvider 65 | * @throws Exception 66 | */ 67 | public static void setLineSpacingProvider(StyledText styledText, ILineSpacingProvider lineSpacingProvider) 68 | throws Exception { 69 | 70 | // 1) As it's not possible to override StyledTextRenderer#getTextLayout, 71 | // StyledTextRenderer#drawLine methods, 72 | // recreate an instance of StyledTextRenderer with Javassist 73 | Object styledTextRenderer = createStyledTextRenderer(styledText, lineSpacingProvider); 74 | 75 | // 2) Reinitialize the renderer like StyledText constructor does. 76 | // renderer = new StyledTextRenderer(getDisplay(), this); 77 | // renderer.setContent(content); 78 | // renderer.setFont(getFont(), tabLength); 79 | initialize(styledTextRenderer, styledText); 80 | 81 | // 3) Set the the new renderer 82 | getRendererField(styledText).set(styledText, styledTextRenderer); 83 | } 84 | 85 | private static /* org.eclipse.swt.custom.StyledTextRenderer */ Object createStyledTextRenderer( 86 | StyledText styledText, ILineSpacingProvider lineSpacingProvider) throws Exception { 87 | // get the org.eclipse.swt.custom.StyledTextRenderer instance of 88 | // StyledText 89 | /* org.eclipse.swt.custom.StyledTextRenderer */ Object originalRenderer = getRendererField(styledText) 90 | .get(styledText); 91 | 92 | // Create a Javassist proxy 93 | ProxyFactory factory = new ProxyFactory(); 94 | factory.setSuperclass(originalRenderer.getClass()); 95 | StyledTextRenderer renderer = new StyledTextRenderer(styledText, originalRenderer.getClass()); 96 | renderer.setLineSpacingProvider(lineSpacingProvider); 97 | factory.setHandler(renderer); 98 | return factory.create(new Class[] { Device.class, StyledText.class }, 99 | new Object[] { styledText.getDisplay(), styledText }); 100 | } 101 | 102 | private static void initialize(Object styledTextRenderer, StyledText styledText) 103 | throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { 104 | // renderer.setContent(content); 105 | Method m1 = getSetContentMethod(styledTextRenderer); 106 | m1.invoke(styledTextRenderer, styledText.getContent()); 107 | // renderer.setFont(getFont(), tabLength); 108 | Method m2 = getSetFontMethod(styledTextRenderer); 109 | m2.invoke(styledTextRenderer, styledText.getFont(), 4); 110 | } 111 | 112 | private static Method getSetContentMethod(Object styledTextRenderer) throws NoSuchMethodException { 113 | // if (SET_CONTENT_METHOD == null) { 114 | Method SET_CONTENT_METHOD = styledTextRenderer.getClass().getDeclaredMethod("setContent", 115 | new Class[] { StyledTextContent.class }); 116 | SET_CONTENT_METHOD.setAccessible(true); 117 | // } 118 | return SET_CONTENT_METHOD; 119 | } 120 | 121 | private static Method getSetFontMethod(Object styledTextRenderer) throws NoSuchMethodException { 122 | // if (SET_FONT_METHOD == null) { 123 | Method SET_FONT_METHOD = styledTextRenderer.getClass().getDeclaredMethod("setFont", 124 | new Class[] { Font.class, int.class }); 125 | SET_FONT_METHOD.setAccessible(true); 126 | // } 127 | return SET_FONT_METHOD; 128 | } 129 | 130 | private static Field getRendererField(StyledText styledText) throws Exception { 131 | if (RENDERER_FIELD == null) { 132 | RENDERER_FIELD = styledText.getClass().getDeclaredField("renderer"); 133 | RENDERER_FIELD.setAccessible(true); 134 | } 135 | return RENDERER_FIELD; 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/swt/custom/patch/StyledTextRenderer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-2017 Angelo ZERR. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * Angelo Zerr - initial API and implementation 10 | */ 11 | package org.eclipse.swt.custom.patch; 12 | 13 | import java.lang.reflect.Field; 14 | import java.lang.reflect.Method; 15 | 16 | import org.eclipse.swt.custom.StyledText; 17 | import org.eclipse.swt.custom.patch.internal.StyledTextRendererEmulator; 18 | import org.eclipse.swt.custom.provisional.ILineSpacingProvider; 19 | import org.eclipse.swt.graphics.TextLayout; 20 | 21 | /** 22 | * Class which should replace the private class 23 | * {@link org.eclipse.swt.custom.StyledTextRenderer} to support line spacing for 24 | * a given line. 25 | * 26 | */ 27 | public class StyledTextRenderer extends StyledTextRendererEmulator { 28 | 29 | private ILineSpacingProvider lineSpacingProvider; 30 | 31 | private final StyledText styledText; 32 | 33 | private final Class swtRendererClass; 34 | 35 | private boolean computing; 36 | 37 | private int topIndex; 38 | 39 | private TextLayout[] layouts; 40 | 41 | public StyledTextRenderer(StyledText styledText, Class swtRendererClass) { 42 | this.styledText = styledText; 43 | this.swtRendererClass = swtRendererClass; 44 | } 45 | 46 | public void setLineSpacingProvider(ILineSpacingProvider lineSpacingProvider) { 47 | this.lineSpacingProvider = lineSpacingProvider; 48 | } 49 | 50 | @Override 51 | protected TextLayout getTextLayout(int lineIndex, int orientation, int width, int lineSpacing, Object obj, 52 | Method proceed, Object[] args) throws Exception { 53 | if (lineSpacingProvider == null) { 54 | return super.getTextLayout(lineIndex, orientation, width, lineSpacing, obj, proceed, args); 55 | } 56 | 57 | // Compute line spacing for the given line index. 58 | int newLineSpacing = lineSpacing; 59 | Integer spacing = lineSpacingProvider.getLineSpacing(lineIndex); 60 | if (spacing != null) { 61 | newLineSpacing = spacing; 62 | } 63 | 64 | Field f = swtRendererClass.getDeclaredField("topIndex"); 65 | f.setAccessible(true); 66 | this.topIndex = (int) f.get(obj); 67 | f = swtRendererClass.getDeclaredField("layouts"); 68 | f.setAccessible(true); 69 | this.layouts = (TextLayout[]) f.get(obj); 70 | 71 | if (isSameLineSpacing(lineIndex, newLineSpacing)) { 72 | return super.getTextLayout(lineIndex, orientation, width, newLineSpacing, obj, proceed, args); 73 | } 74 | 75 | TextLayout layout = super.getTextLayout(lineIndex, orientation, width, lineSpacing, obj, proceed, args); 76 | if (layout.getSpacing() != newLineSpacing) { 77 | layout.setSpacing(newLineSpacing); 78 | if (computing) { 79 | return layout; 80 | } 81 | try { 82 | computing = true; 83 | StyledTextPatcher.resetCache(styledText, lineIndex, styledText.getLineCount()); 84 | StyledTextPatcher.setVariableLineHeight(styledText); 85 | StyledTextPatcher.setCaretLocation(styledText); 86 | styledText.redraw(); 87 | } finally { 88 | computing = false; 89 | } 90 | } 91 | return layout; 92 | } 93 | 94 | boolean isSameLineSpacing(int lineIndex, int newLineSpacing) { 95 | if (layouts == null) { 96 | return false; 97 | } 98 | int layoutIndex = lineIndex - topIndex; 99 | if (0 <= layoutIndex && layoutIndex < layouts.length) { 100 | TextLayout layout = layouts[layoutIndex]; 101 | return layout != null && !layout.isDisposed() && layout.getSpacing() == newLineSpacing; 102 | } 103 | return false; 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/swt/custom/patch/internal/StyledTextRendererEmulator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-2017 Angelo ZERR. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * Angelo Zerr - initial API and implementation 10 | */ 11 | package org.eclipse.swt.custom.patch.internal; 12 | 13 | import java.lang.reflect.Method; 14 | 15 | import org.eclipse.swt.graphics.TextLayout; 16 | 17 | import javassist.util.proxy.MethodHandler; 18 | 19 | /** 20 | * Javassist method handler to override getTextLayout of StyledTextRenderer. 21 | * 22 | */ 23 | public class StyledTextRendererEmulator implements MethodHandler { 24 | 25 | @Override 26 | public Object invoke(Object obj, Method thisMethod, Method proceed, Object[] args) throws Throwable { 27 | if ("getTextLayout".equals(thisMethod.getName()) && args.length > 1) { 28 | int lineIndex = (int) args[0]; 29 | int orientation = (int) args[1]; 30 | int width = (int) args[2]; 31 | int lineSpacing = (int) args[3]; 32 | return getTextLayout(lineIndex, orientation, width, lineSpacing, obj, proceed, args); 33 | } 34 | return proceed.invoke(obj, args); 35 | } 36 | 37 | protected TextLayout getTextLayout(int lineIndex, int orientation, int width, int lineSpacing, Object obj, 38 | Method proceed, Object[] args) throws Exception { 39 | args[0] = lineIndex; 40 | args[1] = orientation; 41 | args[2] = width; 42 | args[3] = lineSpacing; 43 | return (TextLayout) proceed.invoke(obj, args); 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /org.eclipse.codelens/src/org/eclipse/swt/custom/provisional/ILineSpacingProvider.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-2017 Angelo ZERR. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * Angelo Zerr - initial API and implementation 10 | */ 11 | package org.eclipse.swt.custom.provisional; 12 | 13 | public interface ILineSpacingProvider { 14 | 15 | Integer getLineSpacing(int lineIndex); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | fr.opensagres.js 5 | codelens 6 | 1.1.0-SNAPSHOT 7 | pom 8 | 9 | 10 | EditorConfig for Eclipse 11 | https://github.com/angelozerr/codelens-eclipse 12 | 13 | 2016 14 | 15 | 16 | 17 | Eclipse Public License 18 | http://www.eclipse.org/legal/epl-v10.html 19 | repo 20 | 21 | 22 | 23 | org.eclipse.codelens 24 | org.eclipse.codelens.editors 25 | org.eclipse.codelens.jface.fragment 26 | org.eclipse.codelens.swt.fragment 27 | org.eclipse.codelens.jdt 28 | org.eclipse.codelens.feature 29 | org.eclipse.codelens.repository 30 | 31 | 32 | 33 | scm:git:https://github.com/angelozerr/codelens-eclipse.git 34 | scm:git:https://github.com/angelozerr/codelens-eclipse.git 35 | https://github.com/angelozerr/codelens-eclipse 36 | 37 | 38 | 39 | 40 | 41 | org.eclipse.tycho 42 | tycho-maven-plugin 43 | 1.0.0 44 | true 45 | 46 | 47 | org.eclipse.tycho 48 | target-platform-configuration 49 | 1.0.0 50 | true 51 | 52 | p2 53 | consider 54 | 55 | 56 | win32 57 | win32 58 | x86_64 59 | 60 | 61 | win32 62 | win32 63 | x86 64 | 65 | 66 | linux 67 | gtk 68 | x86_64 69 | 70 | 71 | linux 72 | gtk 73 | x86 74 | 75 | 76 | macosx 77 | cocoa 78 | x86_64 79 | 80 | 81 | 82 | 83 | 84 | org.eclipse.tycho 85 | tycho-source-plugin 86 | 1.0.0 87 | 88 | 89 | plugin-source 90 | 91 | plugin-source 92 | 93 | 94 | 95 | 96 | 97 | org.eclipse.tycho.extras 98 | tycho-source-feature-plugin 99 | 1.0.0 100 | 101 | 102 | source-feature 103 | package 104 | 105 | source-feature 106 | 107 | 108 | 109 | 110 | 111 | org.eclipse.tycho 112 | tycho-p2-plugin 113 | 1.0.0 114 | 115 | 116 | attach-p2-metadata 117 | package 118 | 119 | p2-metadata 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | oxygen 130 | p2 131 | http://download.eclipse.org/releases/oxygen 132 | 133 | 134 | orbit 135 | p2 136 | http://download.eclipse.org/tools/orbit/downloads/drops/S20170804160030/repository 137 | 138 | 139 | license-feature 140 | http://download.eclipse.org/cbi/updates/license/ 141 | p2 142 | 143 | 144 | --------------------------------------------------------------------------------