diff options
207 files changed, 12452 insertions, 0 deletions
diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/.project b/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/.project new file mode 100644 index 000000000..2d03c15ec --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.fx.code.compensator.app.feature</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.pde.FeatureBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.FeatureNature</nature> + </natures> +</projectDescription> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/build.properties b/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/build.properties new file mode 100644 index 000000000..b045d3976 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml
\ No newline at end of file diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/feature.xml b/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/feature.xml new file mode 100644 index 000000000..ee1859a16 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/feature.xml @@ -0,0 +1,539 @@ +<?xml version="1.0" encoding="UTF-8"?> +<feature + id="org.eclipse.fx.code.compensator.app.feature" + label="CodeCompansator Application Feature" + version="1.0.0.qualifier" + provider-name="BestSolution.at"> + + <description url="http://www.efxclipse.org"> + TODO FILL WITH CONTENT + </description> + + <copyright url="http://www.efxclipse.org"> + TODO FILL WITH CONTENT + </copyright> + + <license url="http://www.efxclipse.org"> + TODO FILL WITH CONTENT + </license> + + <plugin + id="org.eclipse.fx.code.compensator.app" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.ui.keybindings" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.ui.keybindings.e4" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.ui.keybindings.generic" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.core.databinding" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.ui.databinding" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.core" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.core.fxml" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.ui.di" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.ui.dialogs" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.javafx" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.osgi" + download-size="0" + install-size="0" + version="0.0.0" + fragment="true" + unpack="false"/> + + <plugin + id="org.eclipse.fx.osgi.util" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.ui.panes" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.ui.controls" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.ui.services" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.ui.theme" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.ui.workbench.base" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.ui.workbench.fx" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.ui.workbench.renderers.base" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.ui.workbench.renderers.fx" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.ui.lifecycle" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="com.ibm.icu" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="javax.annotation" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="javax.inject" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="javax.xml" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.apache.commons.logging" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.apache.commons.lang" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.core.commands" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.core.contenttype" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.core.databinding" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.core.databinding.observable" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.core.databinding.property" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.core.expressions" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.core.filesystem" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.core.jobs" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.core.resources" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.core.runtime" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.e4.core.commands" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.e4.core.contexts" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.e4.core.di" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.e4.core.di.extensions" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.e4.core.services" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.e4.ui.di" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.e4.ui.model.workbench" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.e4.ui.services" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.e4.ui.workbench" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.emf.common" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.emf.databinding" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.emf.ecore" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.emf.ecore.change" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.emf.ecore.xmi" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.equinox.app" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.equinox.common" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.equinox.concurrent" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.equinox.ds" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.equinox.event" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.equinox.launcher" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.equinox.preferences" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.equinox.registry" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.equinox.util" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.osgi" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.osgi.services" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.equinox.console" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.apache.felix.gogo.command" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.apache.felix.gogo.runtime" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.apache.felix.gogo.shell" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.code.compensator.freeedit" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.code.compensator.editor" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.code.compensator.editor.contrib" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.code.compensator.editor.java" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.code.compensator.editor.js" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.code.compensator.editor.xml" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.fx.code.compensator.model" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + +</feature> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/pom.xml b/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/pom.xml new file mode 100644 index 000000000..6ee292e8f --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.feature/pom.xml @@ -0,0 +1,16 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <name>CodeCompansator - application feature</name> + <groupId>org.eclipse.fx.code.compensator</groupId> + <artifactId>org.eclipse.fx.code.compensator.app.feature</artifactId> + <packaging>eclipse-feature</packaging> + + <parent> + <groupId>org.eclipse.fx.code.compensator</groupId> + <artifactId>org.eclipse.fx.code.compensator.app.releng</artifactId> + <relativePath>../org.eclipse.fx.code.compensator.app.releng/pom.xml</relativePath> + <version>1.0.0-SNAPSHOT</version> + </parent> + +</project>
\ No newline at end of file diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.product/.project b/experimental/compensator/org.eclipse.fx.code.compensator.app.product/.project new file mode 100644 index 000000000..d9bb836db --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.product/.project @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.fx.code.compensator.app.product</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + </buildSpec> + <natures> + </natures> +</projectDescription> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.product/org.eclipse.fx.code.compensator.app.product.product b/experimental/compensator/org.eclipse.fx.code.compensator.app.product/org.eclipse.fx.code.compensator.app.product.product new file mode 100644 index 000000000..6639e839c --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.product/org.eclipse.fx.code.compensator.app.product.product @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?pde version="3.5"?> + +<product name="CodeCompansator" uid="org.eclipse.fx.code.compensator.app.product" id="org.eclipse.fx.code.compensator.app.product" application="org.eclipse.fx.ui.workbench.fx.application" version="1.0.0" useFeatures="true" includeLaunchers="false"> + + <configIni use="default"> + </configIni> + <launcherArgs> + <programArgs>-nosplash</programArgs> + <vmArgs>-Dosgi.framework.extensions=org.eclipse.fx.osgi</vmArgs> + </launcherArgs> + + <windowImages/> + + <features> + <feature id="org.eclipse.fx.code.compensator.app.feature" version="1.0.0.qualifier"/> + </features> + <configurations> + <plugin id="org.eclipse.core.runtime" autoStart="true" startLevel="0" /> + <plugin id="org.eclipse.equinox.common" autoStart="true" startLevel="2" /> + <plugin id="org.eclipse.equinox.ds" autoStart="true" startLevel="1" /> + <plugin id="org.eclipse.osgi" autoStart="true" startLevel="-1" /> + </configurations> +</product> + diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.product/org.eclipse.fx.code.compensator.app.product.product.launch b/experimental/compensator/org.eclipse.fx.code.compensator.app.product/org.eclipse.fx.code.compensator.app.product.product.launch new file mode 100644 index 000000000..f96da1547 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.product/org.eclipse.fx.code.compensator.app.product.product.launch @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<launchConfiguration type="org.eclipse.pde.ui.RuntimeWorkbench"> +<setAttribute key="additional_plugins"/> +<booleanAttribute key="append.args" value="true"/> +<booleanAttribute key="askclear" value="false"/> +<booleanAttribute key="automaticAdd" value="false"/> +<booleanAttribute key="automaticValidate" value="false"/> +<stringAttribute key="bootstrap" value=""/> +<stringAttribute key="checked" value="[NONE]"/> +<booleanAttribute key="clearConfig" value="false"/> +<booleanAttribute key="clearws" value="true"/> +<booleanAttribute key="clearwslog" value="false"/> +<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/org.eclipse.fx.code.compensator.app.product.product"/> +<booleanAttribute key="default" value="false"/> +<stringAttribute key="featureDefaultLocation" value="workspace"/> +<stringAttribute key="featurePluginResolution" value="workspace"/> +<booleanAttribute key="includeOptional" value="true"/> +<stringAttribute key="location" value="${workspace_loc}/../runtime-org.eclipse.fx.code.compensator.app.product"/> +<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/> +<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> +<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nl ${target.nl} -consoleLog -nosplash"/> +<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/> +<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dosgi.framework.extensions=org.eclipse.fx.osgi"/> +<stringAttribute key="pde.version" value="3.3"/> +<stringAttribute key="product" value="org.eclipse.fx.code.compensator.app.product"/> +<stringAttribute key="productFile" value="/org.eclipse.fx.code.compensator.app.product/org.eclipse.fx.code.compensator.app.product.product"/> +<setAttribute key="selected_features"> +<setEntry value="org.eclipse.fx.code.compensator.app.feature:default"/> +</setAttribute> +<booleanAttribute key="show_selected_only" value="false"/> +<booleanAttribute key="tracing" value="false"/> +<booleanAttribute key="useCustomFeatures" value="true"/> +<booleanAttribute key="useDefaultConfig" value="true"/> +<booleanAttribute key="useDefaultConfigArea" value="true"/> +<booleanAttribute key="useProduct" value="true"/> +<booleanAttribute key="usefeatures" value="false"/> +</launchConfiguration> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.product/pom.xml b/experimental/compensator/org.eclipse.fx.code.compensator.app.product/pom.xml new file mode 100644 index 000000000..39b0f0436 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.product/pom.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <name>CodeCompansator - application product</name> + <groupId>org.eclipse.fx.code.compensator</groupId> + <artifactId>org.eclipse.fx.code.compensator.app.product</artifactId> + <packaging>eclipse-repository</packaging> + + <parent> + <groupId>org.eclipse.fx.code.compensator</groupId> + <artifactId>org.eclipse.fx.code.compensator.app.releng</artifactId> + <relativePath>../org.eclipse.fx.code.compensator.app.releng/pom.xml</relativePath> + <version>1.0.0-SNAPSHOT</version> + </parent> + + <build> + <plugins> + <plugin> + <groupId>org.eclipse.tycho</groupId> + <artifactId>tycho-p2-director-plugin</artifactId> + <version>${tycho-version}</version> + <executions> + <execution> + <id>materialize-products</id> + <goals> + <goal>materialize-products</goal> + </goals> + </execution> + <execution> + <id>archive-products</id> + <goals> + <goal>archive-products</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project>
\ No newline at end of file diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/.project b/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/.project new file mode 100644 index 000000000..c932070c5 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/.project @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.fx.code.compensator.app.releng</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + </buildSpec> + <natures> + </natures> +</projectDescription> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/build.xml b/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/build.xml new file mode 100644 index 000000000..7943919cf --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/build.xml @@ -0,0 +1,51 @@ +<project name="native-build" default="do-deploy" basedir="." xmlns:fx="javafx:com.sun.javafx.tools.ant"> + <property name="eclipse-app-dir" value="../org.eclipse.fx.code.compensator.app.product/target/products/org.eclipse.fx.code.compensator.app.product/noenv/noenv/noenv" /> + + <target name="init-fx-tasks"> + <taskdef name="fxosgilauncher" classpath="org.eclipse.fx.ide.ant.jar" classname="org.eclipse.fx.ide.ant.FXOsgiLaunchTask" /> + <path id="fxant"> + <filelist> + <file name="${java.home}\..\lib\ant-javafx.jar"/> + <file name="${java.home}\lib\ant-jfxrt.jar"/> + </filelist> + </path> + <taskdef resource="com/sun/javafx/tools/ant/antlib.xml" + uri="javafx:com.sun.javafx.tools.ant" + classpathref="fxant"/> + </target> + + <target name="do-deploy" depends="init-fx-tasks"> + <fileset id="equinox-launcher" dir="../org.eclipse.fx.code.compensator.app.product/target/products/org.eclipse.fx.code.compensator.app.product/noenv/noenv/noenv"> + <filename name="plugins/org.eclipse.equinox.launcher_*.jar"/> + </fileset> + <fxosgilauncher classpathref="fxant" equinoxlauncherjarref="equinox-launcher"/> + + <fx:resources id="appRes"> + <fx:fileset dir="." includes="fx-osgi-launch.jar"/> + <fx:fileset dir="${eclipse-app-dir}" includes="**/*"/> + </fx:resources> + + <fx:application id="fxApplication" + name="CodeCompansator" + mainClass="org.eclipse.equinox.launcher.Main" + toolkit="swing" + + /> + + <fx:deploy + embedJNLP="false" + extension="false" + includeDT="false" + offlineAllowed="true" + outdir="${basedir}/deploy" + outfile="fix-ide" + nativeBundles="all" + updatemode="background" + > + + <fx:info title="CodeCompansator" vendor="BestSolution.at"/> + <fx:application refid="fxApplication"/> + <fx:resources refid="appRes"/> + </fx:deploy> + </target> +</project>
\ No newline at end of file diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/org.eclipse.fx.ide.ant.jar b/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/org.eclipse.fx.ide.ant.jar Binary files differnew file mode 100644 index 000000000..45ddf0390 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/org.eclipse.fx.ide.ant.jar diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/pom.xml b/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/pom.xml new file mode 100644 index 000000000..a28f2417f --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app.releng/pom.xml @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" + xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <modelVersion>4.0.0</modelVersion> + <name>CodeCompansator - releng</name> + + <prerequisites> + <maven>3.0</maven> + </prerequisites> + + <groupId>org.eclipse.fx.code.compensator</groupId> + <artifactId>org.eclipse.fx.code.compensator.app.releng</artifactId> + <version>1.0.0-SNAPSHOT</version> + <packaging>pom</packaging> + <properties> + <tycho-version>0.18.0</tycho-version> + <junit-version>4.8.1</junit-version> + <mockito-version>1.8.4</mockito-version> + <platform-version>4.2</platform-version> + <efx-version>0.9.0</efx-version> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <modules> + <module>../org.eclipse.fx.code.compensator.app</module> + <module>../org.eclipse.fx.code.compensator.app.feature</module> + <module>../org.eclipse.fx.code.compensator.app.product</module> + </modules> + + <repositories> + <repository> + <id>efxclipse-repo</id> + <layout>p2</layout> + <url>http://download.eclipse.org/efxclipse/runtime-nightly/site</url> + </repository> + <repository> + <id>efxclipse-addons</id> + <layout>p2</layout> + <url>http://downloads.efxclipse.org/efxclipse.bestsolution.at/p2-repos/runtime/nightly/site/</url> + </repository> + + </repositories> + + <pluginRepositories> + <pluginRepository> + <id>tycho</id> + <url>http://repository.sonatype.org/content/groups/sonatype-public-grid</url> + <snapshots> + <enabled>true</enabled> + </snapshots> + </pluginRepository> + </pluginRepositories> + + <build> + + <!-- build plugins --> + <plugins> + <plugin> + <groupId>org.eclipse.tycho</groupId> + <artifactId>tycho-maven-plugin</artifactId> + <version>${tycho-version}</version> + <extensions>true</extensions> + </plugin> + <plugin> + <groupId>org.eclipse.tycho</groupId> + <artifactId>target-platform-configuration</artifactId> + <version>${tycho-version}</version> + <configuration> + <resolver>p2</resolver> + <pomDependencies>consider</pomDependencies> + <environments> + <environment> + <os>noenv</os> + <ws>noenv</ws> + <arch>noenv</arch> + </environment> + </environments> + </configuration> + </plugin> + </plugins> + + + <!-- defines the default settings for the used plugins --> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.eclipse.tycho</groupId> + <artifactId>tycho-compiler-plugin</artifactId> + <version>${tycho-version}</version> + <configuration> + <encoding>UTF-8</encoding> + <source>1.7</source> + <target>1.7</target> + <extraClasspathElements> + <extraClasspathElement> + <groupId>javafx</groupId> + <artifactId>javafx.mvn</artifactId> + <version>2.2.0-SNAPSHOT</version> + </extraClasspathElement> + </extraClasspathElements> + </configuration> + </plugin> + <plugin> + <groupId>org.eclipse.tycho</groupId> + <artifactId>tycho-source-plugin</artifactId> + <version>${tycho-version}</version> + <executions> + <execution> + <id>plugin-source</id> + <goals> + <goal>plugin-source</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.eclipse.tycho</groupId> + <artifactId>tycho-packaging-plugin</artifactId> + <version>${tycho-version}</version> + <configuration> + <archiveSite>true</archiveSite> + </configuration> + </plugin> + </plugins> + </pluginManagement> + </build> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>${junit-version}</version> + <scope>test</scope> + </dependency> + </dependencies> + </dependencyManagement> + + <dependencies> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <version>${mockito-version}</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + +</project>
\ No newline at end of file diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/.classpath b/experimental/compensator/org.eclipse.fx.code.compensator.app/.classpath new file mode 100644 index 000000000..22f30643c --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/.project b/experimental/compensator/org.eclipse.fx.code.compensator.app/.project new file mode 100644 index 000000000..dce0294c7 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.fx.code.compensator.app</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.pde.PluginNature</nature> + </natures> +</projectDescription> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/Application.e4xmi b/experimental/compensator/org.eclipse.fx.code.compensator.app/Application.e4xmi new file mode 100644 index 000000000..ed874989b --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/Application.e4xmi @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<application:Application xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:advanced="http://www.eclipse.org/ui/2010/UIModel/application/ui/advanced" xmlns:application="http://www.eclipse.org/ui/2010/UIModel/application" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmi:id="_fFsNwPG6EeOigcR0oBysUg" elementId="org.eclipse.fx.code.compensator.app" bindingContexts="_fFq_oPG6EeOigcR0oBysUg"> + <children xsi:type="basic:TrimmedWindow" xmi:id="_xH6dEPG6EeOigcR0oBysUg" elementId="org.eclipse.fx.code.compensator.app.trimmedwindow.0" x="10" y="10" width="800" height="600"> + <children xsi:type="advanced:PerspectiveStack" xmi:id="_mym9kPNkEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.app.perspectivestack.0"/> + <mainMenu xmi:id="_RTKZcPNkEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.app.menu.0"> + <children xsi:type="menu:Menu" xmi:id="_SXdvEPNkEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.app.menu.1" label="File"> + <children xsi:type="menu:HandledMenuItem" xmi:id="_U7ubkPNkEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.app.handledmenuitem.0" label="Open File ..." command="_NKFrQPNkEeOKm6R57HGa4g"/> + </children> + </mainMenu> + </children> + <handlers xmi:id="_FcDokPNkEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.app.handler.0" contributionURI="bundleclass://org.eclipse.fx.code.compensator.app/org.eclipse.fx.code.compensator.app.LoadFile" command="_NKFrQPNkEeOKm6R57HGa4g"/> + <handlers xmi:id="_R3Pi0POkEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.app.handler.1" contributionURI="bundleclass://org.eclipse.fx.code.compensator.app/org.eclipse.fx.code.compensator.app.OpenFile" command="_VwzOUPOkEeOKm6R57HGa4g"/> + <rootContext xmi:id="_fFq_oPG6EeOigcR0oBysUg" elementId="org.eclipse.ui.contexts.dialogAndWindow" name="In Dialog and Windows"> + <children xmi:id="_fFsNwfG6EeOigcR0oBysUg" elementId="org.eclipse.ui.contexts.window" name="In Windows"/> + <children xmi:id="_fFsNwvG6EeOigcR0oBysUg" elementId="org.eclipse.ui.contexts.dialog" name="In Dialogs"/> + </rootContext> + <commands xmi:id="_NKFrQPNkEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.app.command.0" commandName="Load File"/> + <commands xmi:id="_VwzOUPOkEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.app.command.1" commandName="Open File"/> + <addons xmi:id="_fFsNw_G6EeOigcR0oBysUg" elementId="org.eclipse.e4.core.commands.service" contributionURI="bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon"/> + <addons xmi:id="_fFsNxPG6EeOigcR0oBysUg" elementId="org.eclipse.e4.ui.contexts.service" contributionURI="bundleclass://org.eclipse.e4.ui.services/org.eclipse.e4.ui.services.ContextServiceAddon"/> + <addons xmi:id="_fFsNxfG6EeOigcR0oBysUg" elementId="org.eclipse.fx.ui.keybindings.e4.service" contributionURI="bundleclass://org.eclipse.fx.ui.keybindings.e4/org.eclipse.fx.ui.keybindings.e4.BindingServiceAddon"/> + <addons xmi:id="_fFsNxvG6EeOigcR0oBysUg" elementId="org.eclipse.e4.ui.workbench.commands.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.CommandProcessingAddon"/> + <addons xmi:id="_fFsNx_G6EeOigcR0oBysUg" elementId="org.eclipse.e4.ui.workbench.contexts.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.ContextProcessingAddon"/> + <addons xmi:id="_fFsNyPG6EeOigcR0oBysUg" elementId="org.eclipse.fx.ui.keybindings.e4.model" contributionURI="bundleclass://org.eclipse.fx.ui.keybindings.e4/org.eclipse.fx.ui.keybindings.e4.BindingProcessingAddon"/> + <addons xmi:id="_fFsNyfG6EeOigcR0oBysUg" elementId="org.eclipse.e4.ui.workbench.addons.HandlerProcessingAddon" contributionURI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.HandlerProcessingAddon"/> +</application:Application> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.code.compensator.app/META-INF/MANIFEST.MF new file mode 100644 index 000000000..905971556 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/META-INF/MANIFEST.MF @@ -0,0 +1,54 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: My Sample App +Bundle-SymbolicName: org.eclipse.fx.code.compensator.app;singleton:=true +Bundle-Version: 1.0.0.qualifier +Require-Bundle: org.eclipse.fx.ui.workbench.fx, + org.eclipse.e4.ui.model.workbench, + org.eclipse.e4.core.services, + org.eclipse.e4.core.di, + org.eclipse.e4.ui.di, + org.eclipse.e4.core.di.extensions, + org.eclipse.fx.ui.theme, + org.eclipse.fx.ui.di, + org.eclipse.e4.core.contexts, + org.eclipse.fx.core.databinding, + org.eclipse.fx.ui.databinding, + org.eclipse.core.databinding, + org.eclipse.core.databinding.observable, + org.eclipse.core.databinding.property, + org.eclipse.e4.ui.workbench, + org.eclipse.e4.ui.services, + javax.inject, + org.eclipse.fx.code.compensator.model;bundle-version="0.1.0", + org.eclipse.fx.code.compensator.editor;bundle-version="1.0.0" +Import-Package: javafx.animation;version="2.0.0", + javafx.application;version="2.0.0", + javafx.beans;version="2.0.0", + javafx.beans.binding;version="2.0.0", + javafx.beans.property;version="2.0.0", + javafx.beans.value;version="2.0.0", + javafx.collections;version="2.0.0", + javafx.concurrent;version="2.0.0", + javafx.event;version="2.0.0", + javafx.fxml;version="2.0.0", + javafx.geometry;version="2.0.0", + javafx.scene;version="2.0.0", + javafx.scene.chart;version="2.0.0", + javafx.scene.control;version="2.0.0", + javafx.scene.control.cell;version="2.0.0", + javafx.scene.effect;version="2.0.0", + javafx.scene.image;version="2.0.0", + javafx.scene.input;version="2.0.0", + javafx.scene.layout;version="2.0.0", + javafx.scene.media;version="2.0.0", + javafx.scene.paint;version="2.0.0", + javafx.scene.shape;version="2.0.0", + javafx.scene.text;version="2.0.0", + javafx.scene.transform;version="2.0.0", + javafx.scene.web;version="2.0.0", + javafx.stage;version="2.0.0", + javafx.util;version="2.0.0", + javax.annotation;version="1.0.0", + javax.inject;version="1.0.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/bin/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.app/bin/.gitignore new file mode 100644 index 000000000..cf1db2eed --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/bin/.gitignore @@ -0,0 +1 @@ +/org/ diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/build.properties b/experimental/compensator/org.eclipse.fx.code.compensator.app/build.properties new file mode 100644 index 000000000..db411bb01 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/build.properties @@ -0,0 +1,7 @@ +bin.includes = .,\ + META-INF/,\ + plugin.xml,\ +css/,\ + Application.e4xmi + +source.. = src/ diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/css/default.css b/experimental/compensator/org.eclipse.fx.code.compensator.app/css/default.css new file mode 100644 index 000000000..a38730ef4 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/css/default.css @@ -0,0 +1 @@ +/* Main CSS-File */
\ No newline at end of file diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/plugin.xml b/experimental/compensator/org.eclipse.fx.code.compensator.app/plugin.xml new file mode 100644 index 000000000..ba2e02bc0 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/plugin.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.0"?> +<plugin> +<extension id="product" point="org.eclipse.core.runtime.products"> + <product name="CodeCompansator" application="org.eclipse.fx.ui.workbench.fx.application" > + <property name="appName" value="CodeCompansator" /> + + <property name="applicationXMI" value="org.eclipse.fx.code.compensator.app/Application.e4xmi" /> + + <property name="cssTheme" value="theme.default" /> + + </product> + +</extension> +<extension point="org.eclipse.fx.ui.theme"> + <theme id="theme.default" basestylesheet="css/default.css" /> + +</extension> +</plugin> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/pom.xml b/experimental/compensator/org.eclipse.fx.code.compensator.app/pom.xml new file mode 100644 index 000000000..e5b6605fd --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/pom.xml @@ -0,0 +1,33 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <name>CodeCompansator - application bundle</name> + <groupId>org.eclipse.fx.code.compensator</groupId> + <artifactId>org.eclipse.fx.code.compensator.app</artifactId> + <packaging>eclipse-plugin</packaging> + + <parent> + <groupId>org.eclipse.fx.code.compensator</groupId> + <artifactId>org.eclipse.fx.code.compensator.app.releng</artifactId> + <relativePath>../org.eclipse.fx.code.compensator.app.releng/pom.xml</relativePath> + <version>1.0.0-SNAPSHOT</version> + </parent> + + <build> + <resources> + <resource> + <directory>.</directory> + <includes> + <include>META-INF/</include> + </includes> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.eclipse.tycho</groupId> + <artifactId>tycho-source-plugin</artifactId> + </plugin> + </plugins> + </build> + +</project> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/src/org/eclipse/fx/code/compensator/app/LoadFile.java b/experimental/compensator/org.eclipse.fx.code.compensator.app/src/org/eclipse/fx/code/compensator/app/LoadFile.java new file mode 100644 index 000000000..1648a33e2 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/src/org/eclipse/fx/code/compensator/app/LoadFile.java @@ -0,0 +1,47 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.app; + +import java.util.Optional; + +import javafx.stage.FileChooser; +import javafx.stage.Stage; + +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.core.services.events.IEventBroker; +import org.eclipse.fx.code.compensator.model.workbench.Workbench; +import org.eclipse.fx.code.compensator.model.workbench.WorkbenchFactory; + + +public class LoadFile { + @Execute + public void execute(Stage parent, IEventBroker eventBroker, Workbench wb) { + FileChooser chooser = new FileChooser(); + Optional.ofNullable(chooser.showOpenMultipleDialog(parent)).ifPresent((l) -> + { + l.forEach((f) -> { + try { + System.err.println("ATTACHING: " + f); + org.eclipse.fx.code.compensator.model.workbench.File wf = WorkbenchFactory.eINSTANCE.createFile(); + wf.setUrl(f.toURI().toURL().toExternalForm()); + wb.getResources().add(wf); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + }); + + } + ); + + } + +}
\ No newline at end of file diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.app/src/org/eclipse/fx/code/compensator/app/OpenFile.java b/experimental/compensator/org.eclipse.fx.code.compensator.app/src/org/eclipse/fx/code/compensator/app/OpenFile.java new file mode 100644 index 000000000..59053c82e --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.app/src/org/eclipse/fx/code/compensator/app/OpenFile.java @@ -0,0 +1,36 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.app; + +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.e4.ui.workbench.modeling.EPartService; +import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState; +import org.eclipse.emf.common.util.URI; +import org.eclipse.fx.code.compensator.editor.TextEditor; +import org.eclipse.fx.code.compensator.model.workbench.File; + +public class OpenFile { + @Execute + public void openFile(MPerspective perspective, EModelService service, File file, EPartService partService) { + MPartStack element = (MPartStack) service.find("org.eclipse.fx.code.compensator.freeedit.partstack.1", perspective); + + MPart p = service.createModelElement(MPart.class); + p.setContributionURI("bundleclass://org.eclipse.fx.code.compensator.editor/org.eclipse.fx.code.compensator.editor.TextEditor"); + p.getPersistedState().put(TextEditor.DOCUMENT_URL, file.getUrl()); + p.setLabel(URI.createURI(file.getUrl()).lastSegment()); + element.getChildren().add(p); + partService.showPart(p, PartState.ACTIVATE); + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.classpath b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.classpath new file mode 100644 index 000000000..eca7bdba8 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.gitignore new file mode 100644 index 000000000..ae3c17260 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.project b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.project new file mode 100644 index 000000000..546743442 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.project @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.fx.code.compensator.editor.contrib</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ds.core.builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.settings/org.eclipse.jdt.core.prefs b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..0c68a61dc --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/META-INF/MANIFEST.MF new file mode 100644 index 000000000..17e10d4a1 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/META-INF/MANIFEST.MF @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Contrib +Bundle-SymbolicName: org.eclipse.fx.code.compensator.editor.contrib +Bundle-Version: 1.0.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Require-Bundle: org.eclipse.fx.code.compensator.editor;bundle-version="1.0.0", + org.eclipse.e4.core.contexts;bundle-version="1.3.100", + org.eclipse.e4.ui.model.workbench;bundle-version="1.1.0", + org.eclipse.text;bundle-version="3.5.300", + org.eclipse.fx.text;bundle-version="1.0.0", + org.eclipse.fx.text.ui;bundle-version="1.0.0", + org.eclipse.fx.code.compensator.model;bundle-version="0.1.0", + org.eclipse.emf.ecore.xmi;bundle-version="2.10.0" +Service-Component: OSGI-INF/services/servicecollector.xml,OSGI-INF/services/inputcf.xml,OSGI-INF/services/documentcf.xml,OSGI-INF/services/partitionercf.xml,OSGI-INF/services/sourceconfigcf.xml, + OSGI-INF/services/workbenchmodelcf.xml +Bundle-ActivationPolicy: lazy diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/documentcf.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/documentcf.xml new file mode 100644 index 000000000..a42bee538 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/documentcf.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.contrib.documentcf"> + <implementation class="org.eclipse.fx.code.compensator.editor.contrib.DocumentContextFunction"/> + <service> + <provide interface="org.eclipse.e4.core.contexts.IContextFunction"/> + </service> + <property name="service.context.key" type="String" value="org.eclipse.jface.text.IDocument"/> +</scr:component> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/inputcf.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/inputcf.xml new file mode 100644 index 000000000..1129eb4cd --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/inputcf.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.contrib.inputcf"> + <implementation class="org.eclipse.fx.code.compensator.editor.contrib.InputContextFunction"/> + <service> + <provide interface="org.eclipse.e4.core.contexts.IContextFunction"/> + </service> + <property name="service.context.key" type="String" value="org.eclipse.fx.code.compensator.editor.Input"/> +</scr:component> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/partitionercf.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/partitionercf.xml new file mode 100644 index 000000000..4aba18fac --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/partitionercf.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.contrib.partitionercf"> + <implementation class="org.eclipse.fx.code.compensator.editor.contrib.PartitionerContextFunction"/> + <service> + <provide interface="org.eclipse.e4.core.contexts.IContextFunction"/> + </service> + <property name="service.context.key" type="String" value="org.eclipse.jface.text.IDocumentPartitioner"/> +</scr:component> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/servicecollector.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/servicecollector.xml new file mode 100644 index 000000000..008d5f27c --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/servicecollector.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.contrib"> + <implementation class="org.eclipse.fx.code.compensator.editor.contrib.ServiceCollector"/> + <service> + <provide interface="org.eclipse.fx.code.compensator.editor.contrib.ServiceCollector"/> + </service> + <reference bind="addInputFactory" cardinality="0..n" interface="org.eclipse.fx.code.compensator.editor.services.InputFactory" name="InputFactory" policy="dynamic" unbind="removeInputFactory"/> + <reference bind="addDocumentFactory" cardinality="0..n" interface="org.eclipse.fx.code.compensator.editor.services.DocumentFactory" name="DocumentFactory" policy="dynamic" unbind="removeDocumentFactory"/> + <reference bind="addPartitionerFactory" cardinality="0..n" interface="org.eclipse.fx.code.compensator.editor.services.PartitionerFactory" name="PartitionerFactory" policy="dynamic" unbind="removePartitionerFactory"/> + <reference bind="addSourceViewerConfigurationFactory" cardinality="0..n" interface="org.eclipse.fx.code.compensator.editor.services.SourceViewerConfigurationFactory" name="SourceViewerConfigurationFactory" policy="dynamic" unbind="removeSourceViewerConfigurationFactory"/> +</scr:component> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/sourceconfigcf.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/sourceconfigcf.xml new file mode 100644 index 000000000..807b985d6 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/sourceconfigcf.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.contrib.sourceconfig"> + <implementation class="org.eclipse.fx.code.compensator.editor.contrib.SourceViewerConfigurationContextFunction"/> + <service> + <provide interface="org.eclipse.e4.core.contexts.IContextFunction"/> + </service> + <property name="service.context.key" type="String" value="org.eclipse.jface.text.source.SourceViewerConfiguration"/> +</scr:component> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/workbenchmodelcf.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/workbenchmodelcf.xml new file mode 100644 index 000000000..16717f30e --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/OSGI-INF/services/workbenchmodelcf.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.contrib.workbenchmodel"> + <implementation class="org.eclipse.fx.code.compensator.editor.contrib.WorkbenchModelContextFunction"/> + <service> + <provide interface="org.eclipse.e4.core.contexts.IContextFunction"/> + </service> + <property name="service.context.key" type="String" value="org.eclipse.fx.code.compensator.model.workbench.Workbench"/> +</scr:component> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/build.properties b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/build.properties new file mode 100644 index 000000000..d722a551a --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/build.properties @@ -0,0 +1,6 @@ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/,\ + OSGI-INF/services/workbenchmodelcf.xml +source.. = src/ diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/DocumentContextFunction.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/DocumentContextFunction.java new file mode 100644 index 000000000..142ff5172 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/DocumentContextFunction.java @@ -0,0 +1,30 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.contrib; + +import org.eclipse.e4.core.contexts.ContextFunction; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.fx.code.compensator.editor.Input; +import org.eclipse.jface.text.IDocument; + +public class DocumentContextFunction extends ContextFunction { + @Override + public Object compute(IEclipseContext context) { + IDocument document = (IDocument) context.get("localDoc"); + if( document == null ) { + Input<?> input = context.get(Input.class); + ServiceCollector collector = context.get(ServiceCollector.class); + document = collector.createDocument(input); + context.set("localDoc", document); + } + return document; + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/InputContextFunction.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/InputContextFunction.java new file mode 100644 index 000000000..10d513bcb --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/InputContextFunction.java @@ -0,0 +1,33 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.contrib; + +import org.eclipse.e4.core.contexts.ContextFunction; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.fx.code.compensator.editor.Input; +import org.eclipse.fx.code.compensator.editor.TextEditor; + +public class InputContextFunction extends ContextFunction { + @Override + public Object compute(IEclipseContext context) { + Input<?> input = (Input<?>) context.get("localInput"); + if( input == null ) { + MPart part = context.get(MPart.class); + String url = part.getPersistedState().get(TextEditor.DOCUMENT_URL); + + ServiceCollector collector = context.get(ServiceCollector.class); + input = collector.createInput(url); + context.set("localInput", input); + } + return input; + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/PartitionerContextFunction.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/PartitionerContextFunction.java new file mode 100644 index 000000000..6abdf6434 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/PartitionerContextFunction.java @@ -0,0 +1,28 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.contrib; + +import org.eclipse.e4.core.contexts.ContextFunction; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.fx.code.compensator.editor.Input; +import org.eclipse.jface.text.IDocumentPartitioner; + +public class PartitionerContextFunction extends ContextFunction { + @Override + public Object compute(IEclipseContext context) { + IDocumentPartitioner partitioner = (IDocumentPartitioner) context.get("localPartitioner"); + if( partitioner == null ) { + partitioner = context.get(ServiceCollector.class).createPartitioner(context.get(Input.class)); + context.set("localPartitioner", partitioner); + } + return partitioner; + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/ServiceCollector.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/ServiceCollector.java new file mode 100644 index 000000000..8bc2f197d --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/ServiceCollector.java @@ -0,0 +1,85 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.contrib; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.eclipse.fx.code.compensator.editor.Input; +import org.eclipse.fx.code.compensator.editor.services.DocumentFactory; +import org.eclipse.fx.code.compensator.editor.services.InputFactory; +import org.eclipse.fx.code.compensator.editor.services.PartitionerFactory; +import org.eclipse.fx.code.compensator.editor.services.SourceViewerConfigurationFactory; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentPartitioner; +import org.eclipse.jface.text.source.SourceViewerConfiguration; + +public class ServiceCollector { + private List<InputFactory> inputProviderList = new ArrayList<>(); + private List<DocumentFactory> documentProvider = new ArrayList<>(); + private List<PartitionerFactory> partitionerProvider = new ArrayList<>(); + private List<SourceViewerConfigurationFactory> configurationProvider = new ArrayList<>(); + + public void addInputFactory(InputFactory provider) { + inputProviderList.add(provider); + } + + public void removeInputFactory(InputFactory provider) { + inputProviderList.remove(provider); + } + + public void addDocumentFactory(DocumentFactory provider) { + documentProvider.add(provider); + } + + public void removeDocumentFactory(DocumentFactory provider) { + documentProvider.remove(provider); + } + + public void addPartitionerFactory(PartitionerFactory provider) { + partitionerProvider.add(provider); + } + + public void removePartitionerFactory(PartitionerFactory provider) { + partitionerProvider.remove(provider); + } + + public void addSourceViewerConfigurationFactory(SourceViewerConfigurationFactory provider) { + configurationProvider.add(provider); + } + + public void removeSourceViewerConfigurationFactory(SourceViewerConfigurationFactory provider) { + configurationProvider.remove(provider); + } + + public <O> Input<O> createInput(String url) { + System.err.println("PROVIDER: " + inputProviderList); + Optional<Input<O>> map = inputProviderList.stream().filter((p) -> p.applies(url)).findFirst().map((p) -> p.createInput(url)); + return map.get(); + } + + public IDocument createDocument(Input<?> input) { + Optional<IDocument> map = documentProvider.stream().filter((p) -> p.applies(input)).findFirst().map((p) -> p.createDocument(input)); + return map.get(); + } + + public IDocumentPartitioner createPartitioner(Input<?> input) { + System.err.println("PARTITIONER: " + partitionerProvider); + Optional<IDocumentPartitioner> map = partitionerProvider.stream().filter((p) -> p.applies(input)).findFirst().map((p) -> p.createPartitioner(input)); + return map.get(); + } + + public SourceViewerConfiguration createConfiguration(Input<?> input) { + Optional<SourceViewerConfiguration> map = configurationProvider.stream().filter((p) -> p.applies(input)).findFirst().map((p) -> p.createConfiguration(input)); + return map.get(); + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/SourceViewerConfigurationContextFunction.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/SourceViewerConfigurationContextFunction.java new file mode 100644 index 000000000..3cb5617a7 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/SourceViewerConfigurationContextFunction.java @@ -0,0 +1,28 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.contrib; + +import org.eclipse.e4.core.contexts.ContextFunction; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.fx.code.compensator.editor.Input; +import org.eclipse.jface.text.source.SourceViewerConfiguration; + +public class SourceViewerConfigurationContextFunction extends ContextFunction { + @Override + public Object compute(IEclipseContext context) { + SourceViewerConfiguration config = (SourceViewerConfiguration) context.get("localSourceConfig"); + if( config == null ) { + config = context.get(ServiceCollector.class).createConfiguration(context.get(Input.class)); + context.set("localSourceConfig", config); + } + return config; + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/WorkbenchModelContextFunction.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/WorkbenchModelContextFunction.java new file mode 100644 index 000000000..d908b209d --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.contrib/src/org/eclipse/fx/code/compensator/editor/contrib/WorkbenchModelContextFunction.java @@ -0,0 +1,49 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.contrib; + +import java.io.File; +import java.io.IOException; + +import org.eclipse.e4.core.contexts.ContextFunction; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl; +import org.eclipse.fx.code.compensator.model.workbench.Workbench; +import org.eclipse.fx.code.compensator.model.workbench.WorkbenchFactory; + +public class WorkbenchModelContextFunction extends ContextFunction { + @Override + public Object compute(IEclipseContext context) { + context = context.get(MApplication.class).getContext(); + Workbench wb = (Workbench) context.get("LocalWorkbench"); + if( wb == null ) { + File f = new File(System.getProperty("user.home")+"/.compensator/workbench.xmi"); + if( f.exists() ) { + try { + Resource r = new XMIResourceImpl(URI.createFileURI(f.getAbsolutePath())); + r.load(null); + wb = (Workbench) r.getContents().get(0); + context.set("LocalWorkbench", wb); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } else { + wb = WorkbenchFactory.eINSTANCE.createWorkbench(); + context.set("LocalWorkbench", wb); + } + } + return wb; + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.classpath b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.classpath new file mode 100644 index 000000000..eca7bdba8 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.gitignore new file mode 100644 index 000000000..ae3c17260 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.project b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.project new file mode 100644 index 000000000..91ed6a18a --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.project @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.fx.code.compensator.editor.java</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ds.core.builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.settings/org.eclipse.jdt.core.prefs b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..0c68a61dc --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/META-INF/MANIFEST.MF new file mode 100644 index 000000000..24191f667 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/META-INF/MANIFEST.MF @@ -0,0 +1,49 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Java +Bundle-SymbolicName: org.eclipse.fx.code.compensator.editor.java +Bundle-Version: 1.0.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Require-Bundle: org.eclipse.text;bundle-version="3.5.300", + org.eclipse.fx.text;bundle-version="1.0.0", + org.eclipse.equinox.common;bundle-version="3.6.200", + org.eclipse.fx.code.compensator.editor;bundle-version="1.0.0", + org.eclipse.fx.text.ui;bundle-version="1.0.0", + org.eclipse.fx.ui.controls;bundle-version="1.0.0" +Service-Component: OSGI-INF/services/javacomponent.xml +Bundle-ActivationPolicy: lazy +Import-Package: javafx.animation;version="2.2.0", + javafx.application;version="2.2.0", + javafx.beans;version="2.2.0", + javafx.beans.binding;version="2.2.0", + javafx.beans.property;version="2.2.0", + javafx.beans.property.adapter;version="2.2.0", + javafx.beans.value;version="2.2.0", + javafx.collections;version="2.2.0", + javafx.collections.transformation;version="8.0.0", + javafx.concurrent;version="2.2.0", + javafx.css;version="8.0.0", + javafx.embed.swing;version="2.2.0", + javafx.embed.swt;version="2.2.0", + javafx.event;version="2.2.0", + javafx.fxml;version="2.2.0", + javafx.geometry;version="2.2.0", + javafx.print;version="8.0.0", + javafx.scene;version="2.2.0", + javafx.scene.canvas;version="2.2.0", + javafx.scene.chart;version="2.2.0", + javafx.scene.control;version="2.2.0", + javafx.scene.control.cell;version="2.2.0", + javafx.scene.effect;version="2.2.0", + javafx.scene.image;version="2.2.0", + javafx.scene.input;version="2.2.0", + javafx.scene.layout;version="2.2.0", + javafx.scene.media;version="2.2.0", + javafx.scene.paint;version="2.2.0", + javafx.scene.shape;version="2.2.0", + javafx.scene.text;version="2.2.0", + javafx.scene.transform;version="2.2.0", + javafx.scene.web;version="2.2.0", + javafx.stage;version="2.2.0", + javafx.util;version="2.2.0", + javafx.util.converter;version="2.2.0" diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/OSGI-INF/services/javacomponent.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/OSGI-INF/services/javacomponent.xml new file mode 100644 index 000000000..f2b4bbd3e --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/OSGI-INF/services/javacomponent.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.java.javacomponent"> + <implementation class="org.eclipse.fx.code.compensator.editor.java.JavaComponent"/> + <service> + <provide interface="org.eclipse.fx.code.compensator.editor.services.PartitionerFactory"/> + <provide interface="org.eclipse.fx.code.compensator.editor.services.SourceViewerConfigurationFactory"/> + </service> +</scr:component> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/build.properties b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/build.properties new file mode 100644 index 000000000..6de0e8c19 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/build.properties @@ -0,0 +1,5 @@ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/services/javacomponent.xml +source.. = src/ diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/JavaComponent.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/JavaComponent.java new file mode 100644 index 000000000..9e78beef7 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/JavaComponent.java @@ -0,0 +1,52 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.java; + +import org.eclipse.fx.code.compensator.editor.ContentTypeProvider; +import org.eclipse.fx.code.compensator.editor.Input; +import org.eclipse.fx.code.compensator.editor.services.PartitionerFactory; +import org.eclipse.fx.code.compensator.editor.services.SourceViewerConfigurationFactory; +import org.eclipse.jdt.internal.ui.text.FastJavaPartitionScanner; +import org.eclipse.jdt.ui.text.IJavaPartitions; +import org.eclipse.jface.text.IDocumentPartitioner; +import org.eclipse.jface.text.rules.FastPartitioner; +import org.eclipse.jface.text.source.SourceViewerConfiguration; + +public class JavaComponent implements PartitionerFactory, SourceViewerConfigurationFactory { + private final static String[] LEGAL_CONTENT_TYPES= new String[] { + IJavaPartitions.JAVA_DOC, + IJavaPartitions.JAVA_MULTI_LINE_COMMENT, + IJavaPartitions.JAVA_SINGLE_LINE_COMMENT, + IJavaPartitions.JAVA_STRING, + IJavaPartitions.JAVA_CHARACTER + }; + @Override + public SourceViewerConfiguration createConfiguration(Input<?> input) { + return new JavaSourceConfiguration(); + } + + @Override + public boolean applies(Input<?> input) { + if( input instanceof ContentTypeProvider ) { + String contentType = ((ContentTypeProvider) input).getContentType(); + return ContentTypeProvider.JAVA.equals(contentType); + } + return false; + } + + @Override + public IDocumentPartitioner createPartitioner(Input<?> input) { + return new FastPartitioner( + new FastJavaPartitionScanner(), + LEGAL_CONTENT_TYPES); + } + +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/JavaSourceConfiguration.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/JavaSourceConfiguration.java new file mode 100644 index 000000000..f759b0bf3 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/JavaSourceConfiguration.java @@ -0,0 +1,104 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.java; + +import org.eclipse.fx.code.compensator.editor.java.scanner.JavaCodeScanner; +import org.eclipse.fx.code.compensator.editor.java.scanner.JavaCommentScanner; +import org.eclipse.fx.code.compensator.editor.java.scanner.JavaDocScanner; +import org.eclipse.fx.code.compensator.editor.java.scanner.SingleTokenJavaScanner; +import org.eclipse.jdt.ui.text.IJavaColorConstants; +import org.eclipse.jdt.ui.text.IJavaPartitions; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.presentation.IPresentationReconciler; +import org.eclipse.jface.text.presentation.PresentationReconciler; +import org.eclipse.jface.text.rules.DefaultDamagerRepairer; +import org.eclipse.jface.text.rules.ITokenScanner; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.SourceViewerConfiguration; + +public class JavaSourceConfiguration extends SourceViewerConfiguration { + + private JavaCodeScanner fCodeScanner; + private JavaDocScanner fJavaDocScanner; + private JavaCommentScanner fMultilineCommentScanner; + private JavaCommentScanner fSinglelineCommentScanner; + private SingleTokenJavaScanner fStringScanner; + + public JavaSourceConfiguration() { + initializeScanners(); + } + + private void initializeScanners() { + fCodeScanner= new JavaCodeScanner(); + fMultilineCommentScanner= new JavaCommentScanner(IJavaColorConstants.JAVA_MULTI_LINE_COMMENT); + fSinglelineCommentScanner= new JavaCommentScanner(IJavaColorConstants.JAVA_SINGLE_LINE_COMMENT); + fStringScanner= new SingleTokenJavaScanner(IJavaColorConstants.JAVA_STRING); + fJavaDocScanner= new JavaDocScanner(); + } + + @Override + public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) { + return IJavaPartitions.JAVA_PARTITIONING; + } + + @Override + public IPresentationReconciler getPresentationReconciler( + ISourceViewer sourceViewer) { + PresentationReconciler reconciler= new /*JavaPresentationReconciler*/ PresentationReconciler(); + reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer)); + + DefaultDamagerRepairer dr= new DefaultDamagerRepairer(getCodeScanner()); + reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE); + reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE); + + dr= new DefaultDamagerRepairer(getJavaDocScanner()); + reconciler.setDamager(dr, IJavaPartitions.JAVA_DOC); + reconciler.setRepairer(dr, IJavaPartitions.JAVA_DOC); + + dr= new DefaultDamagerRepairer(getMultilineCommentScanner()); + reconciler.setDamager(dr, IJavaPartitions.JAVA_MULTI_LINE_COMMENT); + reconciler.setRepairer(dr, IJavaPartitions.JAVA_MULTI_LINE_COMMENT); + + dr= new DefaultDamagerRepairer(getSinglelineCommentScanner()); + reconciler.setDamager(dr, IJavaPartitions.JAVA_SINGLE_LINE_COMMENT); + reconciler.setRepairer(dr, IJavaPartitions.JAVA_SINGLE_LINE_COMMENT); + + dr= new DefaultDamagerRepairer(getStringScanner()); + reconciler.setDamager(dr, IJavaPartitions.JAVA_STRING); + reconciler.setRepairer(dr, IJavaPartitions.JAVA_STRING); + + dr= new DefaultDamagerRepairer(getStringScanner()); + reconciler.setDamager(dr, IJavaPartitions.JAVA_CHARACTER); + reconciler.setRepairer(dr, IJavaPartitions.JAVA_CHARACTER); + + return reconciler; + } + + private ITokenScanner getStringScanner() { + return fStringScanner; + } + + private ITokenScanner getSinglelineCommentScanner() { + return fSinglelineCommentScanner; + } + + private ITokenScanner getMultilineCommentScanner() { + return fMultilineCommentScanner; + } + + private ITokenScanner getJavaDocScanner() { + return fJavaDocScanner; + } + + private ITokenScanner getCodeScanner() { + return fCodeScanner; + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/AbstractJavaScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/AbstractJavaScanner.java new file mode 100644 index 000000000..a9c4616d4 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/AbstractJavaScanner.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2000, 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.java.scanner; + +import java.util.List; + +import javafx.scene.paint.Color; + +import org.eclipse.jdt.ui.text.IJavaColorConstants; +import org.eclipse.jface.text.TextAttribute; +import org.eclipse.jface.text.rules.BufferedRuleBasedScanner; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.Token; + +public abstract class AbstractJavaScanner extends BufferedRuleBasedScanner { + + public AbstractJavaScanner() { + } + + public final void initialize() { + initializeRules(); + } + + abstract protected List<IRule> createRules(); + + private void initializeRules() { + List<IRule> rules= createRules(); + if (rules != null) { + IRule[] result= new IRule[rules.size()]; + rules.toArray(result); + setRules(result); + } + } + + protected Token getToken(String key) { + switch (key) { + case IJavaColorConstants.JAVA_STRING: + return new Token(new TextAttribute(Color.rgb(42, 0, 255))); + case IJavaColorConstants.JAVA_DEFAULT: + return new Token(new TextAttribute(Color.rgb(0,0,0))); + case JavaCodeScanner.ANNOTATION_COLOR_KEY: + return new Token(new TextAttribute(Color.rgb(200, 200, 200))); + case IJavaColorConstants.JAVA_KEYWORD: + return new Token(new TextAttribute(Color.rgb(127, 0, 85))); + case IJavaColorConstants.JAVA_OPERATOR: + return new Token(new TextAttribute(Color.rgb(0, 0, 0))); + case IJavaColorConstants.JAVA_BRACKET: + return new Token(new TextAttribute(Color.rgb(0, 0, 0))); + case IJavaColorConstants.JAVA_KEYWORD_RETURN: + return new Token(new TextAttribute(Color.rgb(127, 0, 85))); + case IJavaColorConstants.TASK_TAG: + return new Token(new TextAttribute(Color.rgb(127, 159, 191))); + case IJavaColorConstants.JAVADOC_LINK: + return new Token(new TextAttribute(Color.rgb(63, 63, 191))); + case IJavaColorConstants.JAVADOC_DEFAULT: + return new Token(new TextAttribute(Color.rgb(63, 95, 191))); + case IJavaColorConstants.JAVA_MULTI_LINE_COMMENT: + return new Token(new TextAttribute(Color.rgb(63, 127, 95))); + case IJavaColorConstants.JAVA_SINGLE_LINE_COMMENT: + return new Token(new TextAttribute(Color.rgb(63, 127, 95))); + case IJavaColorConstants.JAVADOC_TAG: + return new Token(new TextAttribute(Color.rgb(127, 127, 159))); + default: + throw new IllegalStateException("Unknown key '"+ key+"'"); + } + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaCodeScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaCodeScanner.java new file mode 100644 index 000000000..5741ba216 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaCodeScanner.java @@ -0,0 +1,453 @@ +/******************************************************************************* + * Copyright (c) 2000, 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.java.scanner; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.internal.ui.javaeditor.SemanticHighlightings; +import org.eclipse.jdt.internal.ui.text.CombinedWordRule; +import org.eclipse.jdt.internal.ui.text.ISourceVersionDependent; +import org.eclipse.jdt.internal.ui.text.JavaWhitespaceDetector; +import org.eclipse.jdt.internal.ui.text.JavaWordDetector; +import org.eclipse.jdt.ui.PreferenceConstants; +import org.eclipse.jdt.ui.text.IJavaColorConstants; +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.IWhitespaceDetector; +import org.eclipse.jface.text.rules.IWordDetector; +import org.eclipse.jface.text.rules.SingleLineRule; +import org.eclipse.jface.text.rules.Token; +import org.eclipse.jface.text.rules.WhitespaceRule; + +public class JavaCodeScanner extends AbstractJavaScanner { + + private static final String INTERFACE= "interface"; //$NON-NLS-1$ + private static final String RETURN= "return"; //$NON-NLS-1$ + + private static final String ANNOTATION_BASE_KEY= PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + SemanticHighlightings.ANNOTATION; + static final String ANNOTATION_COLOR_KEY= ANNOTATION_BASE_KEY + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX; + + private List<ISourceVersionDependent> fVersionDependentRules= new ArrayList<ISourceVersionDependent>(3); + + private static String[] fgJava14Keywords= { "assert" }; //$NON-NLS-1$ + private static String[] fgJava15Keywords= { "enum" }; //$NON-NLS-1$ + + static String[] fgKeywords= { + "abstract", //$NON-NLS-1$ + "break", //$NON-NLS-1$ + "case", "catch", "class", "const", "continue", //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ + "default", "do", //$NON-NLS-2$ //$NON-NLS-1$ + "else", "extends", //$NON-NLS-2$ //$NON-NLS-1$ + "final", "finally", "for", //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ + "goto", //$NON-NLS-1$ + "if", "implements", "import", "instanceof", "interface", //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ + "native", "new", //$NON-NLS-2$ //$NON-NLS-1$ + "package", "private", "protected", "public", //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ + "static", "super", "switch", "synchronized", //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ + "this", "throw", "throws", "transient", "try", //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ + "volatile", //$NON-NLS-1$ + "while" //$NON-NLS-1$ + }; + + private static String[] fgTypes= { "void", "boolean", "char", "byte", "short", "strictfp", "int", "long", "float", "double" }; //$NON-NLS-1$ //$NON-NLS-5$ //$NON-NLS-7$ //$NON-NLS-6$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-2$ + private static String[] fgConstants= { "false", "null", "true" }; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ + + public JavaCodeScanner() { + initialize(); + } + +// @Override +// public IToken nextToken() { +// IToken nextToken = super.nextToken(); +// System.err.println("FIND TOKEN: " + nextToken.getData()); +// return nextToken; +// } + + @Override + protected List<IRule> createRules() { + List<IRule> rules= new ArrayList<IRule>(); + + Token token= getToken(IJavaColorConstants.JAVA_STRING); + rules.add(new SingleLineRule("'", "'", token, '\\')); //$NON-NLS-2$ //$NON-NLS-1$ + + Token defaultToken= getToken(IJavaColorConstants.JAVA_DEFAULT); + + // Add generic whitespace rule. + rules.add(new WhitespaceRule(new JavaWhitespaceDetector(), defaultToken)); + +// String version= getPreferenceStore().getString(SOURCE_VERSION); + String version = JavaCore.VERSION_1_8; + + token= getToken(ANNOTATION_COLOR_KEY); + AnnotationRule atInterfaceRule= new AnnotationRule(getToken(IJavaColorConstants.JAVA_KEYWORD), token, JavaCore.VERSION_1_5, version); + rules.add(atInterfaceRule); + fVersionDependentRules.add(atInterfaceRule); + + // Add word rule for new keywords, see bug 4077 + JavaWordDetector wordDetector= new JavaWordDetector(); + CombinedWordRule combinedWordRule= new CombinedWordRule(wordDetector, defaultToken); + + VersionedWordMatcher j14Matcher= new VersionedWordMatcher(defaultToken, JavaCore.VERSION_1_4, version); + + token= getToken(IJavaColorConstants.JAVA_KEYWORD); + for (int i=0; i<fgJava14Keywords.length; i++) + j14Matcher.addWord(fgJava14Keywords[i], token); + + combinedWordRule.addWordMatcher(j14Matcher); + fVersionDependentRules.add(j14Matcher); + + VersionedWordMatcher j15Matcher= new VersionedWordMatcher(defaultToken, JavaCore.VERSION_1_5, version); + + token= getToken(IJavaColorConstants.JAVA_KEYWORD); + for (int i=0; i<fgJava15Keywords.length; i++) + j15Matcher.addWord(fgJava15Keywords[i], token); + + combinedWordRule.addWordMatcher(j15Matcher); + fVersionDependentRules.add(j15Matcher); + + // Add rule for operators + token= getToken(IJavaColorConstants.JAVA_OPERATOR); + rules.add(new OperatorRule(token)); + + // Add rule for brackets + token= getToken(IJavaColorConstants.JAVA_BRACKET); + rules.add(new BracketRule(token)); + + // Add word rule for keyword 'return'. + CombinedWordRule.WordMatcher returnWordRule= new CombinedWordRule.WordMatcher(); + token= getToken(IJavaColorConstants.JAVA_KEYWORD_RETURN); + returnWordRule.addWord(RETURN, token); + combinedWordRule.addWordMatcher(returnWordRule); + + // Add word rule for keywords, types, and constants. + CombinedWordRule.WordMatcher wordRule= new CombinedWordRule.WordMatcher(); + token= getToken(IJavaColorConstants.JAVA_KEYWORD); + for (int i=0; i<fgKeywords.length; i++) + wordRule.addWord(fgKeywords[i], token); + for (int i=0; i<fgTypes.length; i++) + wordRule.addWord(fgTypes[i], token); + for (int i=0; i<fgConstants.length; i++) + wordRule.addWord(fgConstants[i], token); + + combinedWordRule.addWordMatcher(wordRule); + + rules.add(combinedWordRule); + + setDefaultReturnToken(defaultToken); + return rules; + } + + /** + * An annotation rule matches the '@' symbol, any following whitespace and + * optionally a following <code>interface</code> keyword. + * + * It does not match if there is a comment between the '@' symbol and + * the identifier. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=82452 + * + * @since 3.1 + */ + private static class AnnotationRule implements IRule, ISourceVersionDependent { + /** + * A resettable scanner supports marking a position in a scanner and + * unreading back to the marked position. + */ + private static final class ResettableScanner implements ICharacterScanner { + private final ICharacterScanner fDelegate; + private int fReadCount; + + /** + * Creates a new resettable scanner that will forward calls + * to <code>scanner</code>, but store a marked position. + * + * @param scanner the delegate scanner + */ + public ResettableScanner(final ICharacterScanner scanner) { + Assert.isNotNull(scanner); + fDelegate= scanner; + mark(); + } + + /* + * @see org.eclipse.jface.text.rules.ICharacterScanner#getColumn() + */ + public int getColumn() { + return fDelegate.getColumn(); + } + + /* + * @see org.eclipse.jface.text.rules.ICharacterScanner#getLegalLineDelimiters() + */ + public char[][] getLegalLineDelimiters() { + return fDelegate.getLegalLineDelimiters(); + } + + /* + * @see org.eclipse.jface.text.rules.ICharacterScanner#read() + */ + public int read() { + int ch= fDelegate.read(); + if (ch != ICharacterScanner.EOF) + fReadCount++; + return ch; + } + + /* + * @see org.eclipse.jface.text.rules.ICharacterScanner#unread() + */ + public void unread() { + if (fReadCount > 0) + fReadCount--; + fDelegate.unread(); + } + + /** + * Marks an offset in the scanned content. + */ + public void mark() { + fReadCount= 0; + } + + /** + * Resets the scanner to the marked position. + */ + public void reset() { + while (fReadCount > 0) + unread(); + + while (fReadCount < 0) + read(); + } + } + + private final IWhitespaceDetector fWhitespaceDetector= new JavaWhitespaceDetector(); + private final IWordDetector fWordDetector= new JavaWordDetector(); + private final IToken fInterfaceToken; + private final IToken fAtToken; + private final String fVersion; + private boolean fIsVersionMatch; + + /** + * Creates a new rule. + * + * @param interfaceToken the token to return if + * <code>'@\s*interface'</code> is matched + * @param atToken the token to return if <code>'@'</code> + * is matched, but not <code>'@\s*interface'</code> + * @param version the lowest <code>JavaCore.COMPILER_SOURCE</code> + * version that this rule is enabled + * @param currentVersion the current + * <code>JavaCore.COMPILER_SOURCE</code> version + */ + public AnnotationRule(IToken interfaceToken, Token atToken, String version, String currentVersion) { + fInterfaceToken= interfaceToken; + fAtToken= atToken; + fVersion= version; + setSourceVersion(currentVersion); + } + + /* + * @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner) + */ + public IToken evaluate(ICharacterScanner scanner) { + if (!fIsVersionMatch) + return Token.UNDEFINED; + + ResettableScanner resettable= new ResettableScanner(scanner); + if (resettable.read() == '@') + return readAnnotation(resettable); + + resettable.reset(); + return Token.UNDEFINED; + } + + private IToken readAnnotation(ResettableScanner scanner) { + scanner.mark(); + skipWhitespace(scanner); + if (readInterface(scanner)) { + return fInterfaceToken; + } else { + scanner.reset(); + return fAtToken; + } + } + + private boolean readInterface(ICharacterScanner scanner) { + int ch= scanner.read(); + int i= 0; + while (i < INTERFACE.length() && INTERFACE.charAt(i) == ch) { + i++; + ch= scanner.read(); + } + if (i < INTERFACE.length()) + return false; + + if (fWordDetector.isWordPart((char) ch)) + return false; + + if (ch != ICharacterScanner.EOF) + scanner.unread(); + + return true; + } + + private boolean skipWhitespace(ICharacterScanner scanner) { + while (fWhitespaceDetector.isWhitespace((char) scanner.read())) { + // do nothing + } + + scanner.unread(); + return true; + } + + /* + * @see org.eclipse.jdt.internal.ui.text.ISourceVersionDependent#setSourceVersion(java.lang.String) + */ + public void setSourceVersion(String version) { + fIsVersionMatch= fVersion.compareTo(version) <= 0; + } + + } + + private static class VersionedWordMatcher extends CombinedWordRule.WordMatcher implements ISourceVersionDependent { + + private final IToken fDefaultToken; + private final String fVersion; + private boolean fIsVersionMatch; + + public VersionedWordMatcher(IToken defaultToken, String version, String currentVersion) { + fDefaultToken= defaultToken; + fVersion= version; + setSourceVersion(currentVersion); + } + + /* + * @see org.eclipse.jdt.internal.ui.text.ISourceVersionDependent#setSourceVersion(java.lang.String) + */ + public void setSourceVersion(String version) { + fIsVersionMatch= fVersion.compareTo(version) <= 0; + } + + /* + * @see org.eclipse.jdt.internal.ui.text.CombinedWordRule.WordMatcher#evaluate(org.eclipse.jface.text.rules.ICharacterScanner, org.eclipse.jdt.internal.ui.text.CombinedWordRule.CharacterBuffer) + */ + @Override + public IToken evaluate(ICharacterScanner scanner, CombinedWordRule.CharacterBuffer word) { + IToken token= super.evaluate(scanner, word); + + if (fIsVersionMatch || token.isUndefined()) + return token; + + return fDefaultToken; + } + } + + private static final class OperatorRule implements IRule { + + /** Java operators */ + private final char[] JAVA_OPERATORS= { ';', '.', '=', '/', '\\', '+', '-', '*', '<', '>', ':', '?', '!', ',', '|', '&', '^', '%', '~'}; + /** Token to return for this rule */ + private final IToken fToken; + + /** + * Creates a new operator rule. + * + * @param token Token to use for this rule + */ + public OperatorRule(IToken token) { + fToken= token; + } + + /** + * Is this character an operator character? + * + * @param character Character to determine whether it is an operator character + * @return <code>true</code> iff the character is an operator, <code>false</code> otherwise. + */ + public boolean isOperator(char character) { + for (int index= 0; index < JAVA_OPERATORS.length; index++) { + if (JAVA_OPERATORS[index] == character) + return true; + } + return false; + } + + /* + * @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner) + */ + public IToken evaluate(ICharacterScanner scanner) { + + int character= scanner.read(); + if (isOperator((char) character)) { + do { + character= scanner.read(); + } while (isOperator((char) character)); + scanner.unread(); + return fToken; + } else { + scanner.unread(); + return Token.UNDEFINED; + } + } + } + + private static final class BracketRule implements IRule { + + /** Java brackets */ + private final char[] JAVA_BRACKETS= { '(', ')', '{', '}', '[', ']' }; + /** Token to return for this rule */ + private final IToken fToken; + + /** + * Creates a new bracket rule. + * + * @param token Token to use for this rule + */ + public BracketRule(IToken token) { + fToken= token; + } + + /** + * Is this character a bracket character? + * + * @param character Character to determine whether it is a bracket character + * @return <code>true</code> iff the character is a bracket, <code>false</code> otherwise. + */ + public boolean isBracket(char character) { + for (int index= 0; index < JAVA_BRACKETS.length; index++) { + if (JAVA_BRACKETS[index] == character) + return true; + } + return false; + } + + /* + * @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner) + */ + public IToken evaluate(ICharacterScanner scanner) { + + int character= scanner.read(); + if (isBracket((char) character)) { + do { + character= scanner.read(); + } while (isBracket((char) character)); + scanner.unread(); + return fToken; + } else { + scanner.unread(); + return Token.UNDEFINED; + } + } + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaCommentScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaCommentScanner.java new file mode 100644 index 000000000..61b5bc0a2 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaCommentScanner.java @@ -0,0 +1,193 @@ +/******************************************************************************* + * Copyright (c) 2000, 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.java.scanner; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jdt.internal.ui.text.CombinedWordRule; +import org.eclipse.jdt.internal.ui.text.CombinedWordRule.CharacterBuffer; +import org.eclipse.jdt.internal.ui.text.CombinedWordRule.WordMatcher; +import org.eclipse.jdt.ui.text.IJavaColorConstants; +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.IWordDetector; +import org.eclipse.jface.text.rules.Token; + +public class JavaCommentScanner extends AbstractJavaScanner { + protected static final String TASK_TAG= IJavaColorConstants.TASK_TAG; + private TaskTagMatcher fTaskTagMatcher; + private String fDefaultTokenProperty; +// private String[] fTokenProperties; + + public JavaCommentScanner(String defaultTokenProperty) { + this(defaultTokenProperty, new String[] { defaultTokenProperty, TASK_TAG }); + } + + public JavaCommentScanner(String defaultTokenProperty, String[] tokenProperties) { + fDefaultTokenProperty= defaultTokenProperty; +// fTokenProperties= tokenProperties; + initialize(); + } + + @Override + protected List<IRule> createRules() { + List<IRule> list= new ArrayList<IRule>(); + Token defaultToken= getToken(fDefaultTokenProperty); + + List<WordMatcher> matchers= createMatchers(); + if (matchers.size() > 0) { + CombinedWordRule combinedWordRule= new CombinedWordRule(new AtJavaIdentifierDetector(), defaultToken); + for (int i= 0, n= matchers.size(); i < n; i++) + combinedWordRule.addWordMatcher(matchers.get(i)); + list.add(combinedWordRule); + } + + setDefaultReturnToken(defaultToken); + + return list; + } + + protected List<WordMatcher> createMatchers() { + List<WordMatcher> list= new ArrayList<WordMatcher>(); + + // Add rule for Task Tags. + boolean isCaseSensitive= true; + String tasks= "TODO"; +// if (getPreferenceStore().contains(COMPILER_TASK_TAGS)) { +// tasks= getPreferenceStore().getString(COMPILER_TASK_TAGS); +// isCaseSensitive= ENABLED.equals(getPreferenceStore().getString(COMPILER_TASK_CASE_SENSITIVE)); +// } else if (fCorePreferenceStore != null) { +// tasks= fCorePreferenceStore.getString(COMPILER_TASK_TAGS); +// isCaseSensitive= ENABLED.equals(fCorePreferenceStore.getString(COMPILER_TASK_CASE_SENSITIVE)); +// } + if (tasks != null) { + fTaskTagMatcher= new TaskTagMatcher(getToken(TASK_TAG)); + fTaskTagMatcher.addTaskTags(tasks); + fTaskTagMatcher.setCaseSensitive(isCaseSensitive); + list.add(fTaskTagMatcher); + } + + return list; + } + + private class TaskTagMatcher extends CombinedWordRule.WordMatcher { + + private IToken fToken; + /** + * Uppercase words + * @since 3.0 + */ + private Map<CharacterBuffer, IToken> fUppercaseWords= new HashMap<CharacterBuffer, IToken>(); + /** + * <code>true</code> if task tag detection is case-sensitive. + * @since 3.0 + */ + private boolean fCaseSensitive= true; + /** + * Buffer for uppercase word + * @since 3.0 + */ + private CombinedWordRule.CharacterBuffer fBuffer= new CombinedWordRule.CharacterBuffer(16); + + public TaskTagMatcher(IToken token) { + fToken= token; + } + + /* + * @see org.eclipse.jdt.internal.ui.text.CombinedWordRule.WordMatcher#clearWords() + * @since 3.0 + */ + @Override + public synchronized void clearWords() { + super.clearWords(); + fUppercaseWords.clear(); + } + + public synchronized void addTaskTags(String value) { + String[] tasks= split(value, ","); //$NON-NLS-1$ + for (int i= 0; i < tasks.length; i++) { + if (tasks[i].length() > 0) { + addWord(tasks[i], fToken); + } + } + } + + private String[] split(String value, String delimiters) { + StringTokenizer tokenizer= new StringTokenizer(value, delimiters); + int size= tokenizer.countTokens(); + String[] tokens= new String[size]; + int i= 0; + while (i < size) + tokens[i++]= tokenizer.nextToken(); + return tokens; + } + + /* + * @see org.eclipse.jdt.internal.ui.text.CombinedWordRule.WordMatcher#addWord(java.lang.String, org.eclipse.jface.text.rules.IToken) + * @since 3.0 + */ + @Override + public synchronized void addWord(String word, IToken token) { + Assert.isNotNull(word); + Assert.isNotNull(token); + + super.addWord(word, token); + fUppercaseWords.put(new CombinedWordRule.CharacterBuffer(word.toUpperCase()), token); + } + + /* + * @see org.eclipse.jdt.internal.ui.text.CombinedWordRule.WordMatcher#evaluate(org.eclipse.jface.text.rules.ICharacterScanner, org.eclipse.jdt.internal.ui.text.CombinedWordRule.CharacterBuffer) + * @since 3.0 + */ + @Override + public synchronized IToken evaluate(ICharacterScanner scanner, CombinedWordRule.CharacterBuffer word) { + if (fCaseSensitive) + return super.evaluate(scanner, word); + + fBuffer.clear(); + for (int i= 0, n= word.length(); i < n; i++) + fBuffer.append(Character.toUpperCase(word.charAt(i))); + + IToken token= fUppercaseWords.get(fBuffer); + if (token != null) + return token; + return Token.UNDEFINED; + } + + /** + * Enables/disables the case-sensitivity of the task tag detection. + * + * @param caseSensitive <code>true</code> iff case-sensitivity should be enabled + * @since 3.0 + */ + public void setCaseSensitive(boolean caseSensitive) { + fCaseSensitive= caseSensitive; + } + } + + private static class AtJavaIdentifierDetector implements IWordDetector { + + public boolean isWordStart(char c) { + return c == '@' || Character.isJavaIdentifierStart(c); + } + + public boolean isWordPart(char c) { + return c == '.' || Character.isJavaIdentifierPart(c); + } + } + +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaDocScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaDocScanner.java new file mode 100644 index 000000000..0c7557ca2 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/JavaDocScanner.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * Copyright (c) 2000, 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.java.scanner; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jdt.internal.ui.text.JavaWhitespaceDetector; +import org.eclipse.jdt.ui.text.IJavaColorConstants; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.IWordDetector; +import org.eclipse.jface.text.rules.MultiLineRule; +import org.eclipse.jface.text.rules.SingleLineRule; +import org.eclipse.jface.text.rules.Token; +import org.eclipse.jface.text.rules.WhitespaceRule; +import org.eclipse.jface.text.rules.WordRule; + +public class JavaDocScanner extends JavaCommentScanner { + private static String[] fgTokenProperties= { + IJavaColorConstants.JAVADOC_KEYWORD, + IJavaColorConstants.JAVADOC_TAG, + IJavaColorConstants.JAVADOC_LINK, + IJavaColorConstants.JAVADOC_DEFAULT, + TASK_TAG + }; + + + public JavaDocScanner() { + super(IJavaColorConstants.JAVADOC_DEFAULT, fgTokenProperties); + } + + public IDocument getDocument() { + return fDocument; + } + + @Override + protected List<IRule> createRules() { + + List<IRule> list= new ArrayList<IRule>(); + + // Add rule for tags + Token token= getToken(IJavaColorConstants.JAVADOC_TAG); + list.add(new TagRule(token)); + + + // Add rule for HTML comments + WordRule wordRule= new WordRule(new HTMLCommentDetector(), token); + wordRule.addWord("<!--", token); //$NON-NLS-1$ + wordRule.addWord("--!>", token); //$NON-NLS-1$ + list.add(wordRule); + + + // Add rules for links + token= getToken(IJavaColorConstants.JAVADOC_LINK); + list.add(new MultiLineRule("{@link", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$ + list.add(new MultiLineRule("{@value", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$ + list.add(new MultiLineRule("{@inheritDoc", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$ + + // Add rules for @code and @literals + token= getToken(IJavaColorConstants.JAVADOC_DEFAULT); + list.add(new MultiLineRule("{@code", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$ + list.add(new MultiLineRule("{@literal", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$ + + // Add generic whitespace rule + token= getToken(IJavaColorConstants.JAVADOC_DEFAULT); + list.add(new WhitespaceRule(new JavaWhitespaceDetector(), token)); + + + list.addAll(super.createRules()); + return list; + } + + class TagRule extends SingleLineRule { + + /* + * @see SingleLineRule + */ + public TagRule(IToken token) { + super("<", ">", token, (char) 0); //$NON-NLS-2$ //$NON-NLS-1$ + } + + /* + * @see SingleLineRule + */ + public TagRule(IToken token, char escapeCharacter) { + super("<", ">", token, escapeCharacter); //$NON-NLS-2$ //$NON-NLS-1$ + } + + private IToken evaluateToken() { + try { + final String token= getDocument().get(getTokenOffset(), getTokenLength()) + "."; //$NON-NLS-1$ + + int offset= 0; + char character= token.charAt(++offset); + + if (character == '/') + character= token.charAt(++offset); + + while (Character.isWhitespace(character)) + character= token.charAt(++offset); + + while (Character.isLetterOrDigit(character)) + character= token.charAt(++offset); + + while (Character.isWhitespace(character)) + character= token.charAt(++offset); + + if (offset >= 2 && token.charAt(offset) == fEndSequence[0]) + return fToken; + + } catch (BadLocationException exception) { + // Do nothing + } + return getToken(IJavaColorConstants.JAVADOC_DEFAULT); + } + + /* + * @see PatternRule#evaluate(ICharacterScanner) + */ + @Override + public IToken evaluate(ICharacterScanner scanner) { + IToken result= super.evaluate(scanner); + if (result == fToken) + return evaluateToken(); + return result; + } + } + + static class HTMLCommentDetector implements IWordDetector { + + /** + * @see IWordDetector#isWordStart(char) + */ + public boolean isWordStart(char c) { + return (c == '<' || c == '-'); + } + + /** + * @see IWordDetector#isWordPart(char) + */ + public boolean isWordPart(char c) { + return (c == '-' || c == '!' || c == '>'); + } + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/SingleTokenJavaScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/SingleTokenJavaScanner.java new file mode 100644 index 000000000..55508d6eb --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/fx/code/compensator/editor/java/scanner/SingleTokenJavaScanner.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2000, 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.java.scanner; + +import java.util.List; + +import org.eclipse.jface.text.rules.IRule; + +public class SingleTokenJavaScanner extends AbstractJavaScanner{ + private String[] fProperty; + + public SingleTokenJavaScanner(String property) { + super(); + fProperty= new String[] { property }; + initialize(); + } + + @Override + protected List<IRule> createRules() { + setDefaultReturnToken(getToken(fProperty[0])); + return null; + } + +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/core/JavaCore.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/core/JavaCore.java new file mode 100644 index 000000000..5ecb57830 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/core/JavaCore.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2000, 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core; + +public class JavaCore { + public static final String VERSION_1_4 = "1.4"; //$NON-NLS-1$ + public static final String VERSION_1_5 = "1.5"; //$NON-NLS-1$ + public static final String VERSION_1_8 = "1.8"; //$NON-NLS-1$ + +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/JavaPlugin.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/JavaPlugin.java new file mode 100644 index 000000000..b789e0e78 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/JavaPlugin.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2000, 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.ui; + +public class JavaPlugin { + + public static void logErrorMessage(String string) { + System.err.println(string); + } + +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/javaeditor/SemanticHighlightings.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/javaeditor/SemanticHighlightings.java new file mode 100644 index 000000000..1cd813215 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/javaeditor/SemanticHighlightings.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright (c) 2000, 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.ui.javaeditor; + +public class SemanticHighlightings { + public static final String ANNOTATION="annotation"; //$NON-NLS-1$ +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/BufferedDocumentScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/BufferedDocumentScanner.java new file mode 100644 index 000000000..3060ae5ff --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/BufferedDocumentScanner.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.ui.text; + + +import org.eclipse.core.runtime.Assert; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.rules.ICharacterScanner; + +import org.eclipse.jdt.internal.ui.JavaPlugin; + + + +/** + * A buffered document scanner. The buffer always contains a section + * of a fixed size of the document to be scanned. + */ + +public final class BufferedDocumentScanner implements ICharacterScanner { + + /** The document being scanned. */ + private IDocument fDocument; + /** The offset of the document range to scan. */ + private int fRangeOffset; + /** The length of the document range to scan. */ + private int fRangeLength; + /** The delimiters of the document. */ + private char[][] fDelimiters; + + /** The buffer. */ + private final char[] fBuffer; + /** The offset of the buffer within the document. */ + private int fBufferOffset; + /** The valid length of the buffer for access. */ + private int fBufferLength; + /** The offset of the scanner within the buffer. */ + private int fOffset; + + + /** + * Creates a new buffered document scanner. + * The buffer size is set to the given number of characters. + * + * @param size the buffer size + */ + public BufferedDocumentScanner(int size) { + Assert.isTrue(size >= 1); + fBuffer= new char[size]; + } + + /** + * Fills the buffer with the contents of the document starting at the given offset. + * + * @param offset the document offset at which the buffer starts + */ + private final void updateBuffer(int offset) { + + fBufferOffset= offset; + + if (fBufferOffset + fBuffer.length > fRangeOffset + fRangeLength) + fBufferLength= fRangeLength - (fBufferOffset - fRangeOffset); + else + fBufferLength= fBuffer.length; + + try { + final String content= fDocument.get(fBufferOffset, fBufferLength); + content.getChars(0, fBufferLength, fBuffer, 0); + } catch (BadLocationException e) { + } + } + + /** + * Configures the scanner by providing access to the document range over which to scan. + * + * @param document the document to scan + * @param offset the offset of the document range to scan + * @param length the length of the document range to scan + */ + public final void setRange(IDocument document, int offset, int length) { + + fDocument= document; + fRangeOffset= offset; + fRangeLength= length; + + String[] delimiters= document.getLegalLineDelimiters(); + fDelimiters= new char[delimiters.length][]; + for (int i= 0; i < delimiters.length; i++) + fDelimiters[i]= delimiters[i].toCharArray(); + + updateBuffer(offset); + fOffset= 0; + } + + /* + * @see ICharacterScanner#read() + */ + public final int read() { + + if (fOffset == fBufferLength) { + int end= fBufferOffset + fBufferLength; + if (end == fDocument.getLength() || end == fRangeOffset + fRangeLength) + return EOF; + else { + updateBuffer(fBufferOffset + fBufferLength); + fOffset= 0; + } + } + + try { + return fBuffer[fOffset++]; + } catch (ArrayIndexOutOfBoundsException ex) { + StringBuffer buf= new StringBuffer(); + buf.append("Detailed state of 'BufferedDocumentScanner:'"); //$NON-NLS-1$ + buf.append("\n\tfOffset= "); //$NON-NLS-1$ + buf.append(fOffset); + buf.append("\n\tfBufferOffset= "); //$NON-NLS-1$ + buf.append(fBufferOffset); + buf.append("\n\tfBufferLength= "); //$NON-NLS-1$ + buf.append(fBufferLength); + buf.append("\n\tfRangeOffset= "); //$NON-NLS-1$ + buf.append(fRangeOffset); + buf.append("\n\tfRangeLength= "); //$NON-NLS-1$ + buf.append(fRangeLength); + JavaPlugin.logErrorMessage(buf.toString()); + throw ex; + } + } + + /* + * @see ICharacterScanner#unread + */ + public final void unread() { + + if (fOffset == 0) { + if (fBufferOffset == fRangeOffset) { + // error: BOF + } else { + updateBuffer(fBufferOffset - fBuffer.length); + fOffset= fBuffer.length - 1; + } + } else { + --fOffset; + } + } + + /* + * @see ICharacterScanner#getColumn() + */ + public final int getColumn() { + + try { + final int offset= fBufferOffset + fOffset; + final int line= fDocument.getLineOfOffset(offset); + final int start= fDocument.getLineOffset(line); + return offset - start; + } catch (BadLocationException e) { + } + + return -1; + } + + /* + * @see ICharacterScanner#getLegalLineDelimiters() + */ + public final char[][] getLegalLineDelimiters() { + return fDelimiters; + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/CombinedWordRule.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/CombinedWordRule.java new file mode 100644 index 000000000..0add2a854 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/CombinedWordRule.java @@ -0,0 +1,375 @@ +/******************************************************************************* + * Copyright (c) 2000, 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.ui.text; + + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.Assert; + +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.IWordDetector; +import org.eclipse.jface.text.rules.Token; + + +/** + * An implementation of <code>IRule</code> capable of detecting words. + * <p> + * Word rules also allow for the association of tokens with specific words. + * That is, not only can the rule be used to provide tokens for exact matches, + * but also for the generalized notion of a word in the context in which it is used. + * A word rules uses a word detector to determine what a word is.</p> + * <p> + * This word rule allows a word detector to be shared among different word matchers. + * Its up to the word matchers to decide if a word matches and, in this a case, which + * token is associated with that word. + * </p> + * + * @see IWordDetector + * @since 3.0 + */ +public class CombinedWordRule implements IRule { + + /** + * Word matcher, that associates matched words with tokens. + */ + public static class WordMatcher { + + /** The table of predefined words and token for this matcher */ + private Map<CharacterBuffer, IToken> fWords= new HashMap<CharacterBuffer, IToken>(); + + /** + * Adds a word and the token to be returned if it is detected. + * + * @param word the word this rule will search for, may not be <code>null</code> + * @param token the token to be returned if the word has been found, may not be <code>null</code> + */ + public void addWord(String word, IToken token) { + Assert.isNotNull(word); + Assert.isNotNull(token); + + fWords.put(new CharacterBuffer(word), token); + } + + /** + * Returns the token associated to the given word and the scanner state. + * + * @param scanner the scanner + * @param word the word + * @return the token or <code>null</code> if none is associated by this matcher + */ + public IToken evaluate(ICharacterScanner scanner, CharacterBuffer word) { + IToken token= fWords.get(word); + if (token != null) + return token; + return Token.UNDEFINED; + } + + /** + * Removes all words. + */ + public void clearWords() { + fWords.clear(); + } + } + + /** + * Character buffer, mutable <b>or</b> suitable for use as key in hash maps. + */ + public static class CharacterBuffer { + + /** Buffer content */ + private char[] fContent; + /** Buffer content size */ + private int fLength= 0; + + /** Is hash code cached? */ + private boolean fIsHashCached= false; + /** The hash code */ + private int fHashCode; + + /** + * Initialize with the given capacity. + * + * @param capacity the initial capacity + */ + public CharacterBuffer(int capacity) { + fContent= new char[capacity]; + } + + /** + * Initialize with the given content. + * + * @param content the initial content + */ + public CharacterBuffer(String content) { + fContent= content.toCharArray(); + fLength= content.length(); + } + + /** + * Empties this buffer. + */ + public void clear() { + fIsHashCached= false; + fLength= 0; + } + + /** + * Appends the given character to the buffer. + * + * @param c the character + */ + public void append(char c) { + fIsHashCached= false; + if (fLength == fContent.length) { + char[] old= fContent; + fContent= new char[old.length << 1]; + System.arraycopy(old, 0, fContent, 0, old.length); + } + fContent[fLength++]= c; + } + + /** + * Returns the length of the content. + * + * @return the length + */ + public int length() { + return fLength; + } + + /** + * Returns the content as string. + * + * @return the content + */ + @Override + public String toString() { + return new String(fContent, 0, fLength); + } + + /** + * Returns the character at the given position. + * + * @param i the position + * @return the character at position <code>i</code> + */ + public char charAt(int i) { + return fContent[i]; + } + + /* + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + if (fIsHashCached) + return fHashCode; + + int hash= 0; + for (int i= 0, n= fLength; i < n; i++) + hash= 29*hash + fContent[i]; + fHashCode= hash; + fIsHashCached= true; + return hash; + } + + + /* + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (!(obj instanceof CharacterBuffer)) + return false; + CharacterBuffer buffer= (CharacterBuffer) obj; + int length= buffer.length(); + if (length != fLength) + return false; + for (int i= 0; i < length; i++) + if (buffer.charAt(i) != fContent[i]) + return false; + return true; + } + + /** + * Is the content equal to the given string? + * + * @param string the string + * @return <code>true</code> iff the content is the same character sequence as in the string + */ + public boolean equals(String string) { + int length= string.length(); + if (length != fLength) + return false; + for (int i= 0; i < length; i++) + if (string.charAt(i) != fContent[i]) + return false; + return true; + } + } + + /** Internal setting for the uninitialized column constraint */ + private static final int UNDEFINED= -1; + + /** The word detector used by this rule */ + private IWordDetector fDetector; + /** The default token to be returned on success and if nothing else has been specified. */ + private IToken fDefaultToken; + /** The column constraint */ + private int fColumn= UNDEFINED; + /** Buffer used for pattern detection */ + private CharacterBuffer fBuffer= new CharacterBuffer(16); + + /** List of word matchers */ + private List<WordMatcher> fMatchers= new ArrayList<WordMatcher>(); + + /** + * Creates a rule which, with the help of an word detector, will return the token + * associated with the detected word. If no token has been associated, the scanner + * will be rolled back and an undefined token will be returned in order to allow + * any subsequent rules to analyze the characters. + * + * @param detector the word detector to be used by this rule, may not be <code>null</code> + * + * @see WordMatcher#addWord(String, IToken) + */ + public CombinedWordRule(IWordDetector detector) { + this(detector, null, Token.UNDEFINED); + } + + /** + * Creates a rule which, with the help of an word detector, will return the token + * associated with the detected word. If no token has been associated, the + * specified default token will be returned. + * + * @param detector the word detector to be used by this rule, may not be <code>null</code> + * @param defaultToken the default token to be returned on success + * if nothing else is specified, may not be <code>null</code> + * + * @see WordMatcher#addWord(String, IToken) + */ + public CombinedWordRule(IWordDetector detector, IToken defaultToken) { + this(detector, null, defaultToken); + } + + /** + * Creates a rule which, with the help of an word detector, will return the token + * associated with the detected word. If no token has been associated, the scanner + * will be rolled back and an undefined token will be returned in order to allow + * any subsequent rules to analyze the characters. + * + * @param detector the word detector to be used by this rule, may not be <code>null</code> + * @param matcher the initial word matcher + * + * @see WordMatcher#addWord(String, IToken) + */ + public CombinedWordRule(IWordDetector detector, WordMatcher matcher) { + this(detector, matcher, Token.UNDEFINED); + } + + /** + * Creates a rule which, with the help of an word detector, will return the token + * associated with the detected word. If no token has been associated, the + * specified default token will be returned. + * + * @param detector the word detector to be used by this rule, may not be <code>null</code> + * @param matcher the initial word matcher + * @param defaultToken the default token to be returned on success + * if nothing else is specified, may not be <code>null</code> + * + * @see WordMatcher#addWord(String, IToken) + */ + public CombinedWordRule(IWordDetector detector, WordMatcher matcher, IToken defaultToken) { + + Assert.isNotNull(detector); + Assert.isNotNull(defaultToken); + + fDetector= detector; + fDefaultToken= defaultToken; + if (matcher != null) + addWordMatcher(matcher); + } + + + /** + * Adds the given matcher. + * + * @param matcher the matcher + */ + public void addWordMatcher(WordMatcher matcher) { + fMatchers.add(matcher); + } + + /** + * Sets a column constraint for this rule. If set, the rule's token + * will only be returned if the pattern is detected starting at the + * specified column. If the column is smaller then 0, the column + * constraint is considered removed. + * + * @param column the column in which the pattern starts + */ + public void setColumnConstraint(int column) { + if (column < 0) + column= UNDEFINED; + fColumn= column; + } + + /* + * @see IRule#evaluate(ICharacterScanner) + */ + public IToken evaluate(ICharacterScanner scanner) { + int c= scanner.read(); + if (fDetector.isWordStart((char) c)) { + if (fColumn == UNDEFINED || (fColumn == scanner.getColumn() - 1)) { + + fBuffer.clear(); + do { + fBuffer.append((char) c); + c= scanner.read(); + } while (c != ICharacterScanner.EOF && fDetector.isWordPart((char) c)); + scanner.unread(); + + for (int i= 0, n= fMatchers.size(); i < n; i++) { + IToken token= fMatchers.get(i).evaluate(scanner, fBuffer); + if (!token.isUndefined()) + return token; + } + + if (fDefaultToken.isUndefined()) + unreadBuffer(scanner); + + return fDefaultToken; + } + } + + scanner.unread(); + return Token.UNDEFINED; + } + + /** + * Returns the characters in the buffer to the scanner. + * + * @param scanner the scanner to be used + */ + private void unreadBuffer(ICharacterScanner scanner) { + for (int i= fBuffer.length() - 1; i >= 0; i--) + scanner.unread(); + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/FastJavaPartitionScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/FastJavaPartitionScanner.java new file mode 100644 index 000000000..a45c23e63 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/FastJavaPartitionScanner.java @@ -0,0 +1,535 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.ui.text; + + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IPartitionTokenScanner; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.Token; + +import org.eclipse.jdt.ui.text.IJavaPartitions; + + +/** + * This scanner recognizes the JavaDoc comments, Java multi line comments, Java single line comments, + * Java strings and Java characters. + */ +public class FastJavaPartitionScanner implements IPartitionTokenScanner, IJavaPartitions { + + // states + private static final int JAVA= 0; + private static final int SINGLE_LINE_COMMENT= 1; + private static final int MULTI_LINE_COMMENT= 2; + private static final int JAVADOC= 3; + private static final int CHARACTER= 4; + private static final int STRING= 5; + + // beginning of prefixes and postfixes + private static final int NONE= 0; + private static final int BACKSLASH= 1; // postfix for STRING and CHARACTER + private static final int SLASH= 2; // prefix for SINGLE_LINE or MULTI_LINE or JAVADOC + private static final int SLASH_STAR= 3; // prefix for MULTI_LINE_COMMENT or JAVADOC + private static final int SLASH_STAR_STAR= 4; // prefix for MULTI_LINE_COMMENT or JAVADOC + private static final int STAR= 5; // postfix for MULTI_LINE_COMMENT or JAVADOC + private static final int CARRIAGE_RETURN=6; // postfix for STRING, CHARACTER and SINGLE_LINE_COMMENT + + /** The scanner. */ + private final BufferedDocumentScanner fScanner= new BufferedDocumentScanner(1000); // faster implementation + + /** The offset of the last returned token. */ + private int fTokenOffset; + /** The length of the last returned token. */ + private int fTokenLength; + + /** The state of the scanner. */ + private int fState; + /** The last significant characters read. */ + private int fLast; + /** The amount of characters already read on first call to nextToken(). */ + private int fPrefixLength; + + // emulate JavaPartitionScanner + private boolean fEmulate= false; + private int fJavaOffset; + private int fJavaLength; + + private final IToken[] fTokens= new IToken[] { + new Token(null), + new Token(JAVA_SINGLE_LINE_COMMENT), + new Token(JAVA_MULTI_LINE_COMMENT), + new Token(JAVA_DOC), + new Token(JAVA_CHARACTER), + new Token(JAVA_STRING) + }; + + public FastJavaPartitionScanner(boolean emulate) { + fEmulate= emulate; + } + + public FastJavaPartitionScanner() { + this(false); + } + + /* + * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken() + */ + public IToken nextToken() { + + // emulate JavaPartitionScanner + if (fEmulate) { + if (fJavaOffset != -1 && fTokenOffset + fTokenLength != fJavaOffset + fJavaLength) { + fTokenOffset += fTokenLength; + return fTokens[JAVA]; + } else { + fJavaOffset= -1; + fJavaLength= 0; + } + } + + fTokenOffset += fTokenLength; + fTokenLength= fPrefixLength; + + while (true) { + final int ch= fScanner.read(); + + // characters + switch (ch) { + case ICharacterScanner.EOF: + if (fTokenLength > 0) { + fLast= NONE; // ignore last + return preFix(fState, JAVA, NONE, 0); + + } else { + fLast= NONE; + fPrefixLength= 0; + return Token.EOF; + } + + case '\r': + // emulate JavaPartitionScanner + if (!fEmulate && fLast != CARRIAGE_RETURN) { + fLast= CARRIAGE_RETURN; + fTokenLength++; + continue; + + } else { + + switch (fState) { + case SINGLE_LINE_COMMENT: + case CHARACTER: + case STRING: + if (fTokenLength > 0) { + IToken token= fTokens[fState]; + + // emulate JavaPartitionScanner + if (fEmulate) { + fTokenLength++; + fLast= NONE; + fPrefixLength= 0; + } else { + fLast= CARRIAGE_RETURN; + fPrefixLength= 1; + } + + fState= JAVA; + return token; + + } else { + consume(); + continue; + } + + default: + consume(); + continue; + } + } + + case '\n': + switch (fState) { + case SINGLE_LINE_COMMENT: + case CHARACTER: + case STRING: + // assert(fTokenLength > 0); + return postFix(fState); + + default: + consume(); + continue; + } + + default: + if (!fEmulate && fLast == CARRIAGE_RETURN) { + switch (fState) { + case SINGLE_LINE_COMMENT: + case CHARACTER: + case STRING: + + int last; + int newState; + switch (ch) { + case '/': + last= SLASH; + newState= JAVA; + break; + + case '*': + last= STAR; + newState= JAVA; + break; + + case '\'': + last= NONE; + newState= CHARACTER; + break; + + case '"': + last= NONE; + newState= STRING; + break; + + case '\r': + last= CARRIAGE_RETURN; + newState= JAVA; + break; + + case '\\': + last= BACKSLASH; + newState= JAVA; + break; + + default: + last= NONE; + newState= JAVA; + break; + } + + fLast= NONE; // ignore fLast + return preFix(fState, newState, last, 1); + + default: + break; + } + } + } + + // states + switch (fState) { + case JAVA: + switch (ch) { + case '/': + if (fLast == SLASH) { + if (fTokenLength - getLastLength(fLast) > 0) { + return preFix(JAVA, SINGLE_LINE_COMMENT, NONE, 2); + } else { + preFix(JAVA, SINGLE_LINE_COMMENT, NONE, 2); + fTokenOffset += fTokenLength; + fTokenLength= fPrefixLength; + break; + } + + } else { + fTokenLength++; + fLast= SLASH; + break; + } + + case '*': + if (fLast == SLASH) { + if (fTokenLength - getLastLength(fLast) > 0) + return preFix(JAVA, MULTI_LINE_COMMENT, SLASH_STAR, 2); + else { + preFix(JAVA, MULTI_LINE_COMMENT, SLASH_STAR, 2); + fTokenOffset += fTokenLength; + fTokenLength= fPrefixLength; + break; + } + + } else { + consume(); + break; + } + + case '\'': + fLast= NONE; // ignore fLast + if (fTokenLength > 0) + return preFix(JAVA, CHARACTER, NONE, 1); + else { + preFix(JAVA, CHARACTER, NONE, 1); + fTokenOffset += fTokenLength; + fTokenLength= fPrefixLength; + break; + } + + case '"': + fLast= NONE; // ignore fLast + if (fTokenLength > 0) + return preFix(JAVA, STRING, NONE, 1); + else { + preFix(JAVA, STRING, NONE, 1); + fTokenOffset += fTokenLength; + fTokenLength= fPrefixLength; + break; + } + + default: + consume(); + break; + } + break; + + case SINGLE_LINE_COMMENT: + consume(); + break; + + case JAVADOC: + switch (ch) { + case '/': + switch (fLast) { + case SLASH_STAR_STAR: + return postFix(MULTI_LINE_COMMENT); + + case STAR: + return postFix(JAVADOC); + + default: + consume(); + break; + } + break; + + case '*': + fTokenLength++; + fLast= STAR; + break; + + default: + consume(); + break; + } + break; + + case MULTI_LINE_COMMENT: + switch (ch) { + case '*': + if (fLast == SLASH_STAR) { + fLast= SLASH_STAR_STAR; + fTokenLength++; + fState= JAVADOC; + } else { + fTokenLength++; + fLast= STAR; + } + break; + + case '/': + if (fLast == STAR) { + return postFix(MULTI_LINE_COMMENT); + } else { + consume(); + break; + } + + default: + consume(); + break; + } + break; + + case STRING: + switch (ch) { + case '\\': + fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH; + fTokenLength++; + break; + + case '\"': + if (fLast != BACKSLASH) { + return postFix(STRING); + + } else { + consume(); + break; + } + + default: + consume(); + break; + } + break; + + case CHARACTER: + switch (ch) { + case '\\': + fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH; + fTokenLength++; + break; + + case '\'': + if (fLast != BACKSLASH) { + return postFix(CHARACTER); + + } else { + consume(); + break; + } + + default: + consume(); + break; + } + break; + } + } + } + + private static final int getLastLength(int last) { + switch (last) { + default: + return -1; + + case NONE: + return 0; + + case CARRIAGE_RETURN: + case BACKSLASH: + case SLASH: + case STAR: + return 1; + + case SLASH_STAR: + return 2; + + case SLASH_STAR_STAR: + return 3; + } + } + + private final void consume() { + fTokenLength++; + fLast= NONE; + } + + private final IToken postFix(int state) { + fTokenLength++; + fLast= NONE; + fState= JAVA; + fPrefixLength= 0; + return fTokens[state]; + } + + private final IToken preFix(int state, int newState, int last, int prefixLength) { + // emulate JavaPartitionScanner + if (fEmulate && state == JAVA && (fTokenLength - getLastLength(fLast) > 0)) { + fTokenLength -= getLastLength(fLast); + fJavaOffset= fTokenOffset; + fJavaLength= fTokenLength; + fTokenLength= 1; + fState= newState; + fPrefixLength= prefixLength; + fLast= last; + return fTokens[state]; + + } else { + fTokenLength -= getLastLength(fLast); + fLast= last; + fPrefixLength= prefixLength; + IToken token= fTokens[state]; + fState= newState; + return token; + } + } + + private static int getState(String contentType) { + + if (contentType == null) + return JAVA; + + else if (contentType.equals(JAVA_SINGLE_LINE_COMMENT)) + return SINGLE_LINE_COMMENT; + + else if (contentType.equals(JAVA_MULTI_LINE_COMMENT)) + return MULTI_LINE_COMMENT; + + else if (contentType.equals(JAVA_DOC)) + return JAVADOC; + + else if (contentType.equals(JAVA_STRING)) + return STRING; + + else if (contentType.equals(JAVA_CHARACTER)) + return CHARACTER; + + else + return JAVA; + } + + /* + * @see IPartitionTokenScanner#setPartialRange(IDocument, int, int, String, int) + */ + public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) { + + fScanner.setRange(document, offset, length); + fTokenOffset= partitionOffset; + fTokenLength= 0; + fPrefixLength= offset - partitionOffset; + fLast= NONE; + + if (offset == partitionOffset) { + // restart at beginning of partition + fState= JAVA; + } else { + fState= getState(contentType); + } + + // emulate JavaPartitionScanner + if (fEmulate) { + fJavaOffset= -1; + fJavaLength= 0; + } + } + + /* + * @see ITokenScanner#setRange(IDocument, int, int) + */ + public void setRange(IDocument document, int offset, int length) { + + fScanner.setRange(document, offset, length); + fTokenOffset= offset; + fTokenLength= 0; + fPrefixLength= 0; + fLast= NONE; + fState= JAVA; + + // emulate JavaPartitionScanner + if (fEmulate) { + fJavaOffset= -1; + fJavaLength= 0; + } + } + + /* + * @see ITokenScanner#getTokenLength() + */ + public int getTokenLength() { + return fTokenLength; + } + + /* + * @see ITokenScanner#getTokenOffset() + */ + public int getTokenOffset() { + return fTokenOffset; + } + +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/ISourceVersionDependent.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/ISourceVersionDependent.java new file mode 100644 index 000000000..0f6bd6aae --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/ISourceVersionDependent.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.ui.text; + + +/** + * Mix-in for any rule that changes its behavior based on the Java source + * version. + * + * @since 3.1 + */ +public interface ISourceVersionDependent { + + /** + * Sets the configured java source version to one of the + * <code>JavaCore.VERSION_X_Y</code> values. + * + * @param version the new java source version + * @see org.eclipse.jdt.core.JavaCore + */ + void setSourceVersion(String version); +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/JavaWhitespaceDetector.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/JavaWhitespaceDetector.java new file mode 100644 index 000000000..c8e4ae289 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/JavaWhitespaceDetector.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.ui.text; + +import org.eclipse.jface.text.rules.IWhitespaceDetector; + + +/** + * A java aware white space detector. + */ +public class JavaWhitespaceDetector implements IWhitespaceDetector { + + public boolean isWhitespace(char c) { + return Character.isWhitespace(c); + } + +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/JavaWordDetector.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/JavaWordDetector.java new file mode 100644 index 000000000..35142f494 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/internal/ui/text/JavaWordDetector.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.ui.text; + + +import org.eclipse.jface.text.rules.IWordDetector; + +/** + * A Java aware word detector. + */ +public class JavaWordDetector implements IWordDetector { + + /* + * @see IWordDetector#isWordStart + */ + public boolean isWordStart(char c) { + return Character.isJavaIdentifierStart(c); + } + + /* + * @see IWordDetector#isWordPart + */ + public boolean isWordPart(char c) { + return Character.isJavaIdentifierPart(c); + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/PreferenceConstants.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/PreferenceConstants.java new file mode 100644 index 000000000..e2b6e8ad3 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/PreferenceConstants.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright (c) 2000, 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.ui; + +public class PreferenceConstants { + public static final String EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX="semanticHighlighting."; //$NON-NLS-1$ + public static final String EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX=".color"; //$NON-NLS-1$ +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/text/IJavaColorConstants.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/text/IJavaColorConstants.java new file mode 100644 index 000000000..6972a0184 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/text/IJavaColorConstants.java @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (c) 2000, 2013 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.ui.text; + +/** + * Color keys used for syntax highlighting Java + * code and Javadoc compliant comments. + * A <code>IColorManager</code> is responsible for mapping + * concrete colors to these keys. + * <p> + * This interface declares static final fields only; it is not intended to be + * implemented. + * </p> + * + * @see org.eclipse.jdt.ui.text.IColorManager + * @see org.eclipse.jdt.ui.text.IColorManagerExtension + * + * @noimplement This interface is not intended to be implemented by clients. + * @noextend This interface is not intended to be extended by clients. + */ +public interface IJavaColorConstants { + + /** + * Note: This constant is for internal use only. Clients should not use this constant. The + * prefix all color constants start with (value <code>"java_"</code>). + */ + String PREFIX= "java_"; //$NON-NLS-1$ + + /** The color key for multi-line comments in Java code + * (value <code>"java_multi_line_comment"</code>). + */ + String JAVA_MULTI_LINE_COMMENT= "java_multi_line_comment"; //$NON-NLS-1$ + + /** The color key for single-line comments in Java code + * (value <code>"java_single_line_comment"</code>). + */ + String JAVA_SINGLE_LINE_COMMENT= "java_single_line_comment"; //$NON-NLS-1$ + + /** The color key for Java keywords in Java code + * (value <code>"java_keyword"</code>). + */ + String JAVA_KEYWORD= "java_keyword"; //$NON-NLS-1$ + + /** The color key for string and character literals in Java code + * (value <code>"java_string"</code>). + */ + String JAVA_STRING= "java_string"; //$NON-NLS-1$ + + /** The color key for method names in Java code + * (value <code>"java_method_name"</code>). + * + * @since 3.0 + * @deprecated replaced as of 3.1 by an equivalent semantic highlighting, see {@link org.eclipse.jdt.internal.ui.javaeditor.SemanticHighlightings#METHOD} + */ + String JAVA_METHOD_NAME= "java_method_name"; //$NON-NLS-1$ + + /** The color key for keyword 'return' in Java code + * (value <code>"java_keyword_return"</code>). + * + * @since 3.0 + */ + String JAVA_KEYWORD_RETURN= "java_keyword_return"; //$NON-NLS-1$ + + /** The color key for operators in Java code + * (value <code>"java_operator"</code>). + * + * @since 3.0 + */ + String JAVA_OPERATOR= "java_operator"; //$NON-NLS-1$ + + /** The color key for brackets in Java code + * (value <code>"java_bracket"</code>). + * + * @since 3.3 + */ + String JAVA_BRACKET= "java_bracket"; //$NON-NLS-1$ + + /** + * The color key for everything in Java code for which no other color is specified + * (value <code>"java_default"</code>). + */ + String JAVA_DEFAULT= "java_default"; //$NON-NLS-1$ + + /** + * The color key for the Java built-in types such as <code>int</code> and <code>char</code> in Java code + * (value <code>"java_type"</code>). + * + * @deprecated no longer used, replaced by <code>JAVA_KEYWORD</code> + */ + String JAVA_TYPE= "java_type"; //$NON-NLS-1$ + + /** + * The color key for annotations + * (value <code>"java_annotation"</code>). + * + * @since 3.1 + * @deprecated replaced as of 3.2 by an equivalent semantic highlighting, see {@link org.eclipse.jdt.internal.ui.javaeditor.SemanticHighlightings#ANNOTATION} + */ + String JAVA_ANNOTATION= "java_annotation"; //$NON-NLS-1$ + + /** + * The color key for task tags in java comments + * (value <code>"java_comment_task_tag"</code>). + * + * @since 2.1 + */ + String TASK_TAG= "java_comment_task_tag"; //$NON-NLS-1$ + + /** + * The color key for JavaDoc keywords (<code>@foo</code>) in JavaDoc comments + * (value <code>"java_doc_keyword"</code>). + */ + String JAVADOC_KEYWORD= "java_doc_keyword"; //$NON-NLS-1$ + + /** + * The color key for HTML tags (<code><foo></code>) in JavaDoc comments + * (value <code>"java_doc_tag"</code>). + */ + String JAVADOC_TAG= "java_doc_tag"; //$NON-NLS-1$ + + /** + * The color key for JavaDoc links (<code>{foo}</code>) in JavaDoc comments + * (value <code>"java_doc_link"</code>). + */ + String JAVADOC_LINK= "java_doc_link"; //$NON-NLS-1$ + + /** + * The color key for everything in JavaDoc comments for which no other color is specified + * (value <code>"java_doc_default"</code>). + */ + String JAVADOC_DEFAULT= "java_doc_default"; //$NON-NLS-1$ + + //---------- Properties File Editor ---------- + + /** + * The color key for keys in a properties file + * (value <code>"pf_coloring_key"</code>). + * + * @since 3.1 + */ + String PROPERTIES_FILE_COLORING_KEY= "pf_coloring_key"; //$NON-NLS-1$ + + /** + * The color key for comments in a properties file + * (value <code>"pf_coloring_comment"</code>). + * + * @since 3.1 + */ + + String PROPERTIES_FILE_COLORING_COMMENT= "pf_coloring_comment"; //$NON-NLS-1$ + + /** + * The color key for values in a properties file + * (value <code>"pf_coloring_value"</code>). + * + * @since 3.1 + */ + String PROPERTIES_FILE_COLORING_VALUE= "pf_coloring_value"; //$NON-NLS-1$ + + /** + * The color key for assignment in a properties file. + * (value <code>"pf_coloring_assignment"</code>). + * + * @since 3.1 + */ + String PROPERTIES_FILE_COLORING_ASSIGNMENT= "pf_coloring_assignment"; //$NON-NLS-1$ + + /** + * The color key for arguments in values in a properties file. + * (value <code>"pf_coloring_argument"</code>). + * + * @since 3.1 + */ + String PROPERTIES_FILE_COLORING_ARGUMENT= "pf_coloring_argument"; //$NON-NLS-1$ +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/text/IJavaPartitions.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/text/IJavaPartitions.java new file mode 100644 index 000000000..f59ab396e --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.java/src/org/eclipse/jdt/ui/text/IJavaPartitions.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.ui.text; + +/** + * Definition of Java partitioning and its partitions. + * + * @since 3.1 + */ +public interface IJavaPartitions { + + /** + * The identifier of the Java partitioning. + */ + String JAVA_PARTITIONING= "___java_partitioning"; //$NON-NLS-1$ + + /** + * The identifier of the single-line (JLS2: EndOfLineComment) end comment partition content type. + */ + String JAVA_SINGLE_LINE_COMMENT= "__java_singleline_comment"; //$NON-NLS-1$ + + /** + * The identifier multi-line (JLS2: TraditionalComment) comment partition content type. + */ + String JAVA_MULTI_LINE_COMMENT= "__java_multiline_comment"; //$NON-NLS-1$ + + /** + * The identifier of the Javadoc (JLS2: DocumentationComment) partition content type. + */ + String JAVA_DOC= "__java_javadoc"; //$NON-NLS-1$ + + /** + * The identifier of the Java string partition content type. + */ + String JAVA_STRING= "__java_string"; //$NON-NLS-1$ + + /** + * The identifier of the Java character partition content type. + */ + String JAVA_CHARACTER= "__java_character"; //$NON-NLS-1$ +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.classpath b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.classpath new file mode 100644 index 000000000..eca7bdba8 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.gitignore new file mode 100644 index 000000000..ae3c17260 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.project b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.project new file mode 100644 index 000000000..74a2cb024 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.fx.code.compensator.editor.js</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.settings/org.eclipse.jdt.core.prefs b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..0c68a61dc --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/META-INF/MANIFEST.MF new file mode 100644 index 000000000..d988f2c09 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/META-INF/MANIFEST.MF @@ -0,0 +1,6 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Js +Bundle-SymbolicName: org.eclipse.fx.code.compensator.editor.js +Bundle-Version: 1.0.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/build.properties b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/build.properties new file mode 100644 index 000000000..34d2e4d2d --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.js/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.DS_Store b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.DS_Store Binary files differnew file mode 100644 index 000000000..81229e8d2 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.DS_Store diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.classpath b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.classpath new file mode 100644 index 000000000..eca7bdba8 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.gitignore new file mode 100644 index 000000000..ae3c17260 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.project b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.project new file mode 100644 index 000000000..2ab33e92d --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.project @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.fx.code.compensator.editor.xml</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ds.core.builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.settings/org.eclipse.jdt.core.prefs b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..0c68a61dc --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/META-INF/MANIFEST.MF new file mode 100644 index 000000000..02f34ceaa --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/META-INF/MANIFEST.MF @@ -0,0 +1,47 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Xml +Bundle-SymbolicName: org.eclipse.fx.code.compensator.editor.xml +Bundle-Version: 1.0.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Require-Bundle: org.eclipse.fx.code.compensator.editor;bundle-version="1.0.0", + org.eclipse.fx.text;bundle-version="1.0.0", + org.eclipse.fx.text.ui;bundle-version="1.0.0", + org.eclipse.fx.ui.controls;bundle-version="1.0.0" +Service-Component: OSGI-INF/services/xmlcomponent.xml +Bundle-ActivationPolicy: lazy +Import-Package: javafx.animation;version="2.2.0", + javafx.application;version="2.2.0", + javafx.beans;version="2.2.0", + javafx.beans.binding;version="2.2.0", + javafx.beans.property;version="2.2.0", + javafx.beans.property.adapter;version="2.2.0", + javafx.beans.value;version="2.2.0", + javafx.collections;version="2.2.0", + javafx.collections.transformation;version="8.0.0", + javafx.concurrent;version="2.2.0", + javafx.css;version="8.0.0", + javafx.embed.swing;version="2.2.0", + javafx.embed.swt;version="2.2.0", + javafx.event;version="2.2.0", + javafx.fxml;version="2.2.0", + javafx.geometry;version="2.2.0", + javafx.print;version="8.0.0", + javafx.scene;version="2.2.0", + javafx.scene.canvas;version="2.2.0", + javafx.scene.chart;version="2.2.0", + javafx.scene.control;version="2.2.0", + javafx.scene.control.cell;version="2.2.0", + javafx.scene.effect;version="2.2.0", + javafx.scene.image;version="2.2.0", + javafx.scene.input;version="2.2.0", + javafx.scene.layout;version="2.2.0", + javafx.scene.media;version="2.2.0", + javafx.scene.paint;version="2.2.0", + javafx.scene.shape;version="2.2.0", + javafx.scene.text;version="2.2.0", + javafx.scene.transform;version="2.2.0", + javafx.scene.web;version="2.2.0", + javafx.stage;version="2.2.0", + javafx.util;version="2.2.0", + javafx.util.converter;version="2.2.0" diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/OSGI-INF/services/xmlcomponent.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/OSGI-INF/services/xmlcomponent.xml new file mode 100644 index 000000000..9358e4c16 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/OSGI-INF/services/xmlcomponent.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.xml.xmlcomponent"> + <implementation class="org.eclipse.fx.code.compensator.editor.xml.XMLComponent"/> + <service> + <provide interface="org.eclipse.fx.code.compensator.editor.services.PartitionerFactory"/> + <provide interface="org.eclipse.fx.code.compensator.editor.services.SourceViewerConfigurationFactory"/> + </service> +</scr:component> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/build.properties b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/build.properties new file mode 100644 index 000000000..11d7f1a1b --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/build.properties @@ -0,0 +1,5 @@ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/services/xmlcomponent.xml +source.. = src/ diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/.DS_Store b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/.DS_Store Binary files differnew file mode 100644 index 000000000..75302fef4 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/.DS_Store diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/.DS_Store b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/.DS_Store Binary files differnew file mode 100644 index 000000000..d5581d0b3 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/.DS_Store diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/.DS_Store b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/.DS_Store Binary files differnew file mode 100644 index 000000000..39c1da9ce --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/.DS_Store diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/.DS_Store b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/.DS_Store Binary files differnew file mode 100644 index 000000000..3c779262d --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/.DS_Store diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/.DS_Store b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/.DS_Store Binary files differnew file mode 100644 index 000000000..d5d042447 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/.DS_Store diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/.DS_Store b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/.DS_Store Binary files differnew file mode 100644 index 000000000..841f408a3 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/.DS_Store diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/.DS_Store b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/.DS_Store Binary files differnew file mode 100644 index 000000000..d8dcc41fa --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/.DS_Store diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/IXMLColorConstants.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/IXMLColorConstants.java new file mode 100644 index 000000000..3d56b75e4 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/IXMLColorConstants.java @@ -0,0 +1,21 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.xml; + +import javafx.scene.paint.Color; + +public interface IXMLColorConstants { + Color XML_COMMENT = Color.rgb(128, 0, 0); + Color PROC_INSTR = Color.rgb(128, 128, 128); + Color STRING = Color.rgb(0, 128, 0); + Color DEFAULT = Color.rgb(0, 0, 0); + Color TAG = Color.rgb(0, 0, 128); +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/NonRuleBasedDamagerRepairer.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/NonRuleBasedDamagerRepairer.java new file mode 100644 index 000000000..1bfe309c8 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/NonRuleBasedDamagerRepairer.java @@ -0,0 +1,148 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.xml; + +import org.eclipse.fx.ui.controls.styledtext.StyleRange; +import org.eclipse.jface.text.Assert; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextAttribute; +import org.eclipse.jface.text.TextPresentation; +import org.eclipse.jface.text.presentation.IPresentationDamager; +import org.eclipse.jface.text.presentation.IPresentationRepairer; + +public class NonRuleBasedDamagerRepairer + implements IPresentationDamager, IPresentationRepairer { + + /** The document this object works on */ + protected IDocument fDocument; + /** The default text attribute if non is returned as data by the current token */ + protected TextAttribute fDefaultTextAttribute; + + /** + * Constructor for NonRuleBasedDamagerRepairer. + */ + public NonRuleBasedDamagerRepairer(TextAttribute defaultTextAttribute) { + Assert.isNotNull(defaultTextAttribute); + + fDefaultTextAttribute = defaultTextAttribute; + } + + /** + * @see IPresentationRepairer#setDocument(IDocument) + */ + public void setDocument(IDocument document) { + fDocument = document; + } + + /** + * Returns the end offset of the line that contains the specified offset or + * if the offset is inside a line delimiter, the end offset of the next line. + * + * @param offset the offset whose line end offset must be computed + * @return the line end offset for the given offset + * @exception BadLocationException if offset is invalid in the current document + */ + protected int endOfLineOf(int offset) throws BadLocationException { + + IRegion info = fDocument.getLineInformationOfOffset(offset); + if (offset <= info.getOffset() + info.getLength()) + return info.getOffset() + info.getLength(); + + int line = fDocument.getLineOfOffset(offset); + try { + info = fDocument.getLineInformation(line + 1); + return info.getOffset() + info.getLength(); + } catch (BadLocationException x) { + return fDocument.getLength(); + } + } + + /** + * @see IPresentationDamager#getDamageRegion(ITypedRegion, DocumentEvent, boolean) + */ + public IRegion getDamageRegion( + ITypedRegion partition, + DocumentEvent event, + boolean documentPartitioningChanged) { + if (!documentPartitioningChanged) { + try { + + IRegion info = + fDocument.getLineInformationOfOffset(event.getOffset()); + int start = Math.max(partition.getOffset(), info.getOffset()); + + int end = + event.getOffset() + + (event.getText() == null + ? event.getLength() + : event.getText().length()); + + if (info.getOffset() <= end + && end <= info.getOffset() + info.getLength()) { + // optimize the case of the same line + end = info.getOffset() + info.getLength(); + } else + end = endOfLineOf(end); + + end = + Math.min( + partition.getOffset() + partition.getLength(), + end); + return new Region(start, end - start); + + } catch (BadLocationException x) { + } + } + + return partition; + } + + /** + * @see IPresentationRepairer#createPresentation(TextPresentation, ITypedRegion) + */ + public void createPresentation( + TextPresentation presentation, + ITypedRegion region) { + addRange( + presentation, + region.getOffset(), + region.getLength(), + fDefaultTextAttribute); + } + + /** + * Adds style information to the given text presentation. + * + * @param presentation the text presentation to be extended + * @param offset the offset of the range to be styled + * @param length the length of the range to be styled + * @param attr the attribute describing the style of the range to be styled + */ + protected void addRange( + TextPresentation presentation, + int offset, + int length, + TextAttribute attr) { + if (attr != null) + presentation.addStyleRange( + new StyleRange( + offset, + length, + attr.getForeground(), + attr.getBackground(), + attr.getStyle())); + } +}
\ No newline at end of file diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/TagRule.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/TagRule.java new file mode 100644 index 000000000..ba497f708 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/TagRule.java @@ -0,0 +1,41 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.xml; + +import org.eclipse.jface.text.rules.*; + +public class TagRule extends MultiLineRule { + + public TagRule(IToken token) { + super("<", ">", token); + } + protected boolean sequenceDetected( + ICharacterScanner scanner, + char[] sequence, + boolean eofAllowed) { + int c = scanner.read(); + if (sequence[0] == '<') { + if (c == '?') { + // processing instruction - abort + scanner.unread(); + return false; + } + if (c == '!') { + scanner.unread(); + // comment - abort + return false; + } + } else if (sequence[0] == '>') { + scanner.unread(); + } + return super.sequenceDetected(scanner, sequence, eofAllowed); + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLComponent.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLComponent.java new file mode 100644 index 000000000..4e9cc9642 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLComponent.java @@ -0,0 +1,46 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.xml; + +import org.eclipse.fx.code.compensator.editor.ContentTypeProvider; +import org.eclipse.fx.code.compensator.editor.Input; +import org.eclipse.fx.code.compensator.editor.services.PartitionerFactory; +import org.eclipse.fx.code.compensator.editor.services.SourceViewerConfigurationFactory; +import org.eclipse.jface.text.IDocumentPartitioner; +import org.eclipse.jface.text.rules.FastPartitioner; +import org.eclipse.jface.text.source.SourceViewerConfiguration; + +public class XMLComponent implements PartitionerFactory, SourceViewerConfigurationFactory { + + @Override + public SourceViewerConfiguration createConfiguration(Input<?> input) { + return new XMLConfiguration(); + } + + @Override + public boolean applies(Input<?> input) { + if( input instanceof ContentTypeProvider ) { + String contentType = ((ContentTypeProvider) input).getContentType(); + return ContentTypeProvider.XML.equals(contentType); + } + return false; + } + + @Override + public IDocumentPartitioner createPartitioner(Input<?> input) { + return new FastPartitioner( + new XMLPartitionScanner(), + new String[] { + XMLPartitionScanner.XML_TAG, + XMLPartitionScanner.XML_COMMENT }); + } + +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLConfiguration.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLConfiguration.java new file mode 100644 index 000000000..cc977d8f9 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLConfiguration.java @@ -0,0 +1,83 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.xml; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.TextAttribute; +import org.eclipse.jface.text.presentation.IPresentationReconciler; +import org.eclipse.jface.text.presentation.PresentationReconciler; +import org.eclipse.jface.text.rules.DefaultDamagerRepairer; +import org.eclipse.jface.text.rules.Token; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.SourceViewerConfiguration; + +public class XMLConfiguration extends SourceViewerConfiguration { +// private XMLDoubleClickStrategy doubleClickStrategy; + private XMLTagScanner tagScanner; + private XMLScanner scanner; + + public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) { + return new String[] { + IDocument.DEFAULT_CONTENT_TYPE, + XMLPartitionScanner.XML_COMMENT, + XMLPartitionScanner.XML_TAG }; + } +// public ITextDoubleClickStrategy getDoubleClickStrategy( +// ISourceViewer sourceViewer, +// String contentType) { +// if (doubleClickStrategy == null) +// doubleClickStrategy = new XMLDoubleClickStrategy(); +// return doubleClickStrategy; +// } + + protected XMLScanner getXMLScanner() { + if (scanner == null) { + scanner = new XMLScanner(); + scanner.setDefaultReturnToken( + new Token( + new TextAttribute(IXMLColorConstants.DEFAULT))); + } + return scanner; + } + protected XMLTagScanner getXMLTagScanner() { + if (tagScanner == null) { + tagScanner = new XMLTagScanner(); + tagScanner.setDefaultReturnToken( + new Token( + new TextAttribute( + IXMLColorConstants.TAG))); + } + return tagScanner; + } + + public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) { + PresentationReconciler reconciler = new PresentationReconciler(); + + DefaultDamagerRepairer dr = + new DefaultDamagerRepairer(getXMLTagScanner()); + reconciler.setDamager(dr, XMLPartitionScanner.XML_TAG); + reconciler.setRepairer(dr, XMLPartitionScanner.XML_TAG); + + dr = new DefaultDamagerRepairer(getXMLScanner()); + reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE); + reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE); + + NonRuleBasedDamagerRepairer ndr = + new NonRuleBasedDamagerRepairer( + new TextAttribute( + IXMLColorConstants.XML_COMMENT)); + reconciler.setDamager(ndr, XMLPartitionScanner.XML_COMMENT); + reconciler.setRepairer(ndr, XMLPartitionScanner.XML_COMMENT); + + return reconciler; + } + +}
\ No newline at end of file diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLPartitionScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLPartitionScanner.java new file mode 100644 index 000000000..d61c8ce96 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLPartitionScanner.java @@ -0,0 +1,31 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.xml; + +import org.eclipse.jface.text.rules.*; + +public class XMLPartitionScanner extends RuleBasedPartitionScanner { + public final static String XML_COMMENT = "__xml_comment"; + public final static String XML_TAG = "__xml_tag"; + + public XMLPartitionScanner() { + + IToken xmlComment = new Token(XML_COMMENT); + IToken tag = new Token(XML_TAG); + + IPredicateRule[] rules = new IPredicateRule[2]; + + rules[0] = new MultiLineRule("<!--", "-->", xmlComment); + rules[1] = new TagRule(tag); + + setPredicateRules(rules); + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLScanner.java new file mode 100644 index 000000000..9fc1e1b0b --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLScanner.java @@ -0,0 +1,32 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.xml; + +import org.eclipse.jface.text.rules.*; +import org.eclipse.jface.text.*; + +public class XMLScanner extends RuleBasedScanner { + + public XMLScanner() { + IToken procInstr = + new Token( + new TextAttribute( + IXMLColorConstants.PROC_INSTR)); + + IRule[] rules = new IRule[2]; + //Add rule for processing instructions + rules[0] = new SingleLineRule("<?", "?>", procInstr); + // Add generic whitespace rule. + rules[1] = new WhitespaceRule(new XMLWhitespaceDetector()); + + setRules(rules); + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLTagScanner.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLTagScanner.java new file mode 100644 index 000000000..7b51b8cfa --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLTagScanner.java @@ -0,0 +1,34 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.xml; + +import org.eclipse.jface.text.*; +import org.eclipse.jface.text.rules.*; + +public class XMLTagScanner extends RuleBasedScanner { + + public XMLTagScanner() { + IToken string = + new Token( + new TextAttribute(IXMLColorConstants.STRING)); + + IRule[] rules = new IRule[3]; + + // Add rule for double quotes + rules[0] = new SingleLineRule("\"", "\"", string, '\\'); + // Add a rule for single quotes + rules[1] = new SingleLineRule("'", "'", string, '\\'); + // Add generic whitespace rule. + rules[2] = new WhitespaceRule(new XMLWhitespaceDetector()); + + setRules(rules); + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLWhitespaceDetector.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLWhitespaceDetector.java new file mode 100644 index 000000000..8e74c7f4f --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor.xml/src/org/eclipse/fx/code/compensator/editor/xml/XMLWhitespaceDetector.java @@ -0,0 +1,20 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.xml; + +import org.eclipse.jface.text.rules.IWhitespaceDetector; + +public class XMLWhitespaceDetector implements IWhitespaceDetector { + + public boolean isWhitespace(char c) { + return (c == ' ' || c == '\t' || c == '\n' || c == '\r'); + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/.classpath b/experimental/compensator/org.eclipse.fx.code.compensator.editor/.classpath new file mode 100644 index 000000000..eca7bdba8 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.editor/.gitignore new file mode 100644 index 000000000..ae3c17260 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/.project b/experimental/compensator/org.eclipse.fx.code.compensator.editor/.project new file mode 100644 index 000000000..c7cfd2686 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/.project @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.fx.code.compensator.editor</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ds.core.builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/.settings/org.eclipse.jdt.core.prefs b/experimental/compensator/org.eclipse.fx.code.compensator.editor/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..0c68a61dc --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.code.compensator.editor/META-INF/MANIFEST.MF new file mode 100644 index 000000000..a54c995ec --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/META-INF/MANIFEST.MF @@ -0,0 +1,52 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Editor +Bundle-SymbolicName: org.eclipse.fx.code.compensator.editor +Bundle-Version: 1.0.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Import-Package: javafx.animation;version="2.2.0", + javafx.application;version="2.2.0", + javafx.beans;version="2.2.0", + javafx.beans.binding;version="2.2.0", + javafx.beans.property;version="2.2.0", + javafx.beans.property.adapter;version="2.2.0", + javafx.beans.value;version="2.2.0", + javafx.collections;version="2.2.0", + javafx.collections.transformation;version="8.0.0", + javafx.concurrent;version="2.2.0", + javafx.css;version="8.0.0", + javafx.embed.swing;version="2.2.0", + javafx.embed.swt;version="2.2.0", + javafx.event;version="2.2.0", + javafx.fxml;version="2.2.0", + javafx.geometry;version="2.2.0", + javafx.print;version="8.0.0", + javafx.scene;version="2.2.0", + javafx.scene.canvas;version="2.2.0", + javafx.scene.chart;version="2.2.0", + javafx.scene.control;version="2.2.0", + javafx.scene.control.cell;version="2.2.0", + javafx.scene.effect;version="2.2.0", + javafx.scene.image;version="2.2.0", + javafx.scene.input;version="2.2.0", + javafx.scene.layout;version="2.2.0", + javafx.scene.media;version="2.2.0", + javafx.scene.paint;version="2.2.0", + javafx.scene.shape;version="2.2.0", + javafx.scene.text;version="2.2.0", + javafx.scene.transform;version="2.2.0", + javafx.scene.web;version="2.2.0", + javafx.stage;version="2.2.0", + javafx.util;version="2.2.0", + javafx.util.converter;version="2.2.0", + javax.annotation;version="1.2.0", + javax.inject;version="1.0.0" +Require-Bundle: org.eclipse.fx.ui.controls;bundle-version="1.0.0", + org.eclipse.text;bundle-version="3.5.300", + org.eclipse.fx.text;bundle-version="1.0.0", + org.eclipse.fx.text.ui;bundle-version="1.0.0" +Export-Package: org.eclipse.fx.code.compensator.editor, + org.eclipse.fx.code.compensator.editor.services +Service-Component: OSGI-INF/services/fileinputprovider.xml, + OSGI-INF/services/defaultdocumentfactory.xml +Bundle-ActivationPolicy: lazy diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/OSGI-INF/services/defaultdocumentfactory.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor/OSGI-INF/services/defaultdocumentfactory.xml new file mode 100644 index 000000000..3ffb0736a --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/OSGI-INF/services/defaultdocumentfactory.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.defaultdocumentfactory"> + <implementation class="org.eclipse.fx.code.compensator.editor.internal.DefaultDocumentFactory"/> + <service> + <provide interface="org.eclipse.fx.code.compensator.editor.services.DocumentFactory"/> + </service> +</scr:component> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/OSGI-INF/services/fileinputprovider.xml b/experimental/compensator/org.eclipse.fx.code.compensator.editor/OSGI-INF/services/fileinputprovider.xml new file mode 100644 index 000000000..15ced386a --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/OSGI-INF/services/fileinputprovider.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.code.compensator.editor.fileinputprovider"> + <implementation class="org.eclipse.fx.code.compensator.editor.internal.FileInputFactory"/> + <service> + <provide interface="org.eclipse.fx.code.compensator.editor.services.InputFactory"/> + </service> +</scr:component> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/build.properties b/experimental/compensator/org.eclipse.fx.code.compensator.editor/build.properties new file mode 100644 index 000000000..d2d37a30e --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/build.properties @@ -0,0 +1,6 @@ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/,\ + OSGI-INF/services/defaultdocumentfactory.xml +source.. = src/ diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/ContentTypeProvider.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/ContentTypeProvider.java new file mode 100644 index 000000000..5eb5ca97f --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/ContentTypeProvider.java @@ -0,0 +1,18 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor; + +public interface ContentTypeProvider { + public static final String XML = "text/xml"; + public static final String JAVA = "text/java"; + public static final String JAVASCRIPT = "text/javascript"; + public String getContentType(); +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/Input.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/Input.java new file mode 100644 index 000000000..69d8d3e1c --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/Input.java @@ -0,0 +1,16 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor; + +public interface Input<O> { + public O getData(); + public void setData(O data); +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/TextEditor.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/TextEditor.java new file mode 100644 index 000000000..07382da8a --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/TextEditor.java @@ -0,0 +1,51 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor; + +import javafx.scene.layout.BorderPane; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentExtension3; +import org.eclipse.jface.text.IDocumentPartitioner; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.jface.text.source.SourceViewerConfiguration; + +public class TextEditor { + public static final String DOCUMENT_URL = "documentUrl"; + + @Inject + IDocument document; + + @Inject + SourceViewerConfiguration configuration; + + @Inject + IDocumentPartitioner partitioner; + + @PostConstruct + public void initUI(BorderPane pane) { + SourceViewer viewer = new SourceViewer(); + if( document instanceof IDocumentExtension3 ) { + ((IDocumentExtension3)document).setDocumentPartitioner(configuration.getConfiguredDocumentPartitioning(viewer),partitioner); + } else { + document.setDocumentPartitioner(partitioner); + } + document.setDocumentPartitioner(partitioner); + partitioner.connect(document); + + viewer.configure(configuration); + viewer.setDocument(document); + pane.setCenter(viewer); + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/DefaultDocumentFactory.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/DefaultDocumentFactory.java new file mode 100644 index 000000000..5240eed45 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/DefaultDocumentFactory.java @@ -0,0 +1,30 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.internal; + +import org.eclipse.fx.code.compensator.editor.Input; +import org.eclipse.fx.code.compensator.editor.services.DocumentFactory; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; + +public class DefaultDocumentFactory implements DocumentFactory { + + @Override + public boolean applies(Input<?> input) { + return input instanceof FileInput; + } + + @Override + public IDocument createDocument(Input<?> input) { + return new Document(((FileInput)input).getData()); + } + +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/FileInput.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/FileInput.java new file mode 100644 index 000000000..2f715f09d --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/FileInput.java @@ -0,0 +1,70 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.internal; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.eclipse.fx.code.compensator.editor.ContentTypeProvider; +import org.eclipse.fx.code.compensator.editor.Input; + +public class FileInput implements Input<String>, ContentTypeProvider { + private Path path; + + public FileInput(Path path) { + this.path = path; + } + + @Override + public String getData() { + try(BufferedReader reader = Files.newBufferedReader(path)) { + StringBuilder b = new StringBuilder(); + String line; + while( (line = reader.readLine()) != null ) { + b.append(line); + } + reader.close(); + return b.toString(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return ""; + } + + @Override + public void setData(String data) { + try(BufferedWriter writer = Files.newBufferedWriter(path)) { + writer.write(data); + writer.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + @Override + public String getContentType() { + //FIXME Need suffix => type mapping + System.err.println("PATH: " + path); + if( path.toString().endsWith(".xml") ) { + return ContentTypeProvider.XML; + } else if( path.toString().endsWith(".java") ) { + return ContentTypeProvider.JAVA; + } else if( path.toString().endsWith(".js") ) { + return ContentTypeProvider.JAVASCRIPT; + } + return null; + } +}
\ No newline at end of file diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/FileInputFactory.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/FileInputFactory.java new file mode 100644 index 000000000..674c96d57 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/internal/FileInputFactory.java @@ -0,0 +1,38 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.internal; + +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Paths; + +import org.eclipse.fx.code.compensator.editor.Input; +import org.eclipse.fx.code.compensator.editor.services.InputFactory; + +public class FileInputFactory implements InputFactory { + @Override + public boolean applies(String url) { + System.err.println("CHECKING: " + url); + return url.startsWith("file:"); + } + + @Override + public <O> Input<O> createInput(String url) { + try { + return (Input<O>) new FileInput(Paths.get(new URI(url))); + } catch (URISyntaxException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/DocumentFactory.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/DocumentFactory.java new file mode 100644 index 000000000..413e5ab2b --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/DocumentFactory.java @@ -0,0 +1,19 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.services; + +import org.eclipse.fx.code.compensator.editor.Input; +import org.eclipse.jface.text.IDocument; + +public interface DocumentFactory { + public boolean applies(Input<?> input); + public IDocument createDocument(Input<?> input); +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/InputFactory.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/InputFactory.java new file mode 100644 index 000000000..a3778631b --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/InputFactory.java @@ -0,0 +1,18 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.services; + +import org.eclipse.fx.code.compensator.editor.Input; + +public interface InputFactory { + public boolean applies(String url); + public <O> Input<O> createInput(String url); +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/PartitionerFactory.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/PartitionerFactory.java new file mode 100644 index 000000000..0424d6f26 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/PartitionerFactory.java @@ -0,0 +1,19 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.services; + +import org.eclipse.fx.code.compensator.editor.Input; +import org.eclipse.jface.text.IDocumentPartitioner; + +public interface PartitionerFactory { + public boolean applies(Input<?> input); + public IDocumentPartitioner createPartitioner(Input<?> input); +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/SourceViewerConfigurationFactory.java b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/SourceViewerConfigurationFactory.java new file mode 100644 index 000000000..4ec14eb96 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.editor/src/org/eclipse/fx/code/compensator/editor/services/SourceViewerConfigurationFactory.java @@ -0,0 +1,19 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.editor.services; + +import org.eclipse.fx.code.compensator.editor.Input; +import org.eclipse.jface.text.source.SourceViewerConfiguration; + +public interface SourceViewerConfigurationFactory { + public boolean applies(Input<?> input); + public SourceViewerConfiguration createConfiguration(Input<?> input); +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.classpath b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.classpath new file mode 100644 index 000000000..eca7bdba8 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.gitignore new file mode 100644 index 000000000..ae3c17260 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.project b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.project new file mode 100644 index 000000000..045afcaff --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.fx.code.compensator.freeedit</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.settings/org.eclipse.jdt.core.prefs b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..0c68a61dc --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/META-INF/MANIFEST.MF new file mode 100644 index 000000000..a3e89d2d8 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/META-INF/MANIFEST.MF @@ -0,0 +1,48 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Freeedit +Bundle-SymbolicName: org.eclipse.fx.code.compensator.freeedit;singleton:=true +Bundle-Version: 1.0.0.qualifier +Require-Bundle: org.eclipse.e4.ui.model.workbench;bundle-version="1.1.0.v20140512-1820", + org.eclipse.fx.code.compensator.model;bundle-version="0.1.0", + org.eclipse.e4.core.commands;bundle-version="0.10.2", + org.eclipse.core.commands;bundle-version="3.6.100", + org.eclipse.e4.core.contexts;bundle-version="1.3.100" +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Import-Package: javafx.animation;version="2.2.0", + javafx.application;version="2.2.0", + javafx.beans;version="2.2.0", + javafx.beans.binding;version="2.2.0", + javafx.beans.property;version="2.2.0", + javafx.beans.property.adapter;version="2.2.0", + javafx.beans.value;version="2.2.0", + javafx.collections;version="2.2.0", + javafx.collections.transformation;version="8.0.0", + javafx.concurrent;version="2.2.0", + javafx.css;version="8.0.0", + javafx.embed.swing;version="2.2.0", + javafx.embed.swt;version="2.2.0", + javafx.event;version="2.2.0", + javafx.fxml;version="2.2.0", + javafx.geometry;version="2.2.0", + javafx.print;version="8.0.0", + javafx.scene;version="2.2.0", + javafx.scene.canvas;version="2.2.0", + javafx.scene.chart;version="2.2.0", + javafx.scene.control;version="2.2.0", + javafx.scene.control.cell;version="2.2.0", + javafx.scene.effect;version="2.2.0", + javafx.scene.image;version="2.2.0", + javafx.scene.input;version="2.2.0", + javafx.scene.layout;version="2.2.0", + javafx.scene.media;version="2.2.0", + javafx.scene.paint;version="2.2.0", + javafx.scene.shape;version="2.2.0", + javafx.scene.text;version="2.2.0", + javafx.scene.transform;version="2.2.0", + javafx.scene.web;version="2.2.0", + javafx.stage;version="2.2.0", + javafx.util;version="2.2.0", + javafx.util.converter;version="2.2.0", + javax.annotation;version="1.2.0", + javax.inject;version="1.0.0" diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/build.properties b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/build.properties new file mode 100644 index 000000000..a14e838a6 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/build.properties @@ -0,0 +1,6 @@ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + fragment.e4xmi,\ + plugin.xml +source.. = src/ diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/fragment.e4xmi b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/fragment.e4xmi new file mode 100644 index 000000000..a5ef9b374 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/fragment.e4xmi @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="ASCII"?> +<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:advanced="http://www.eclipse.org/ui/2010/UIModel/application/ui/advanced" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmi:id="_JIaJEPNlEeOKm6R57HGa4g"> + <fragments xsi:type="fragment:StringModelFragment" xmi:id="_R9qSgPNlEeOKm6R57HGa4g" featurename="children" parentElementId="org.eclipse.fx.code.compensator.app.perspectivestack.0"> + <elements xsi:type="advanced:Perspective" xmi:id="_Zg4MUPNlEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.freeedit.perspective.0" label="Free edit"> + <children xsi:type="basic:PartSashContainer" xmi:id="_ejlRMPNlEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.freeedit.partsashcontainer.0" horizontal="true"> + <children xsi:type="basic:PartStack" xmi:id="_fgaF0PNlEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.freeedit.partstack.0" containerData="20"> + <children xsi:type="basic:Part" xmi:id="_iX7skPNlEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.freeedit.part.0" contributionURI="bundleclass://org.eclipse.fx.code.compensator.freeedit/org.eclipse.fx.code.compensator.freeedit.FileList" label="Files" iconURI="platform:/plugin/org.eclipse.fx.code.compensator.freeedit/icons/22/view-list-tree.png"/> + </children> + <children xsi:type="basic:PartStack" xmi:id="_f6c9gPNlEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.freeedit.partstack.1" containerData="60"/> + <children xsi:type="basic:PartStack" xmi:id="_gQ-nIPNlEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.freeedit.partstack.2" containerData="20"> + <children xsi:type="basic:Part" xmi:id="_tzdUsPNlEeOKm6R57HGa4g" elementId="org.eclipse.fx.code.compensator.freeedit.part.1" contributionURI="bundleclass://org.eclipse.fx.code.compensator.freeedit/org.eclipse.fx.code.compensator.freeedit.FileOutline" label="Outline" iconURI="platform:/plugin/org.eclipse.fx.code.compensator.freeedit/icons/22/code-class.png"/> + </children> + </children> + </elements> + </fragments> +</fragment:ModelFragments> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/icons/22/code-class.png b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/icons/22/code-class.png Binary files differnew file mode 100644 index 000000000..225aca941 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/icons/22/code-class.png diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/icons/22/view-list-tree.png b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/icons/22/view-list-tree.png Binary files differnew file mode 100644 index 000000000..b1dde396c --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/icons/22/view-list-tree.png diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/plugin.xml b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/plugin.xml new file mode 100644 index 000000000..53fd90f33 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/plugin.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plugin> + + <extension + id="org.eclipse.fx.code.compensator.freeedit.fragment" + point="org.eclipse.e4.workbench.model"> + <fragment + apply="notexists" + uri="fragment.e4xmi"> + </fragment> + </extension> + +</plugin> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/src/org/eclipse/fx/code/compensator/freeedit/FileList.java b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/src/org/eclipse/fx/code/compensator/freeedit/FileList.java new file mode 100644 index 000000000..5e7c41794 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/src/org/eclipse/fx/code/compensator/freeedit/FileList.java @@ -0,0 +1,101 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.freeedit; + +import java.util.Collections; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.BorderPane; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; + +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.e4.core.commands.ECommandService; +import org.eclipse.e4.core.commands.EHandlerService; +import org.eclipse.e4.core.contexts.EclipseContextFactory; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.impl.AdapterImpl; +import org.eclipse.emf.common.util.URI; +import org.eclipse.fx.code.compensator.model.workbench.File; +import org.eclipse.fx.code.compensator.model.workbench.Resource; +import org.eclipse.fx.code.compensator.model.workbench.Workbench; +import org.eclipse.fx.code.compensator.model.workbench.WorkbenchPackage; + +@SuppressWarnings("restriction") +public class FileList { + @Inject + private Workbench workbench; + + @Inject + private ECommandService commandService; + + @Inject + private EHandlerService handlerService; + + private ObservableList<Resource> inputList = FXCollections.observableArrayList(); + + private ListView<Resource> view; + + @PostConstruct + public void initUI(BorderPane parent) { + view = new ListView<>(); + view.setCellFactory(FileList::listCell); + view.setItems(inputList); + view.setOnMouseClicked(this::open); + parent.setCenter(view); + workbench.eAdapters().add(new AdapterImpl() { + @Override + public void notifyChanged(Notification msg) { + if( msg.getFeature() == WorkbenchPackage.Literals.WORKBENCH_ELEMENT__RESOURCES ) { + if( msg.getEventType() == Notification.ADD ) { + inputList.add((Resource) msg.getNewValue()); + } + } + } + }); + } + + private void open(MouseEvent event) { + if( event.getClickCount() == 2 ) { + Command cmd = commandService.getCommand("org.eclipse.fx.code.compensator.app.command.1"); + IEclipseContext staticCtx = EclipseContextFactory.create(); + staticCtx.set(File.class, (File)view.getSelectionModel().getSelectedItem()); + ParameterizedCommand pCmd = ParameterizedCommand.generateCommand(cmd, Collections.emptyMap()); + handlerService.executeHandler(pCmd, staticCtx); + staticCtx.dispose(); + } + } + + private static ListCell<Resource> listCell(ListView<Resource> param) { + return new ListCell<Resource>() { + @Override + protected void updateItem(Resource item, boolean empty) { + if( item != null && ! empty ) { + if( item instanceof File ) { + URI uri = URI.createURI(((File) item).getUrl()); + setText(uri.lastSegment()); + } + } else { + setText(null); + setGraphic(null); + } + super.updateItem(item, empty); + } + }; + } +}
\ No newline at end of file diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/src/org/eclipse/fx/code/compensator/freeedit/FileOutline.java b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/src/org/eclipse/fx/code/compensator/freeedit/FileOutline.java new file mode 100644 index 000000000..48d30818a --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.freeedit/src/org/eclipse/fx/code/compensator/freeedit/FileOutline.java @@ -0,0 +1,22 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.freeedit; + +import javafx.scene.layout.BorderPane; + +import javax.annotation.PostConstruct; + +public class FileOutline { + @PostConstruct + public void initUI(BorderPane parent) { + + } +} diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/.classpath b/experimental/compensator/org.eclipse.fx.code.compensator.model/.classpath new file mode 100644 index 000000000..2534a1484 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/.classpath @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="src" path="src-gen"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.model/.gitignore new file mode 100644 index 000000000..ae3c17260 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/.project b/experimental/compensator/org.eclipse.fx.code.compensator.model/.project new file mode 100644 index 000000000..82aecc346 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/.project @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.fx.code.compensator.model</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.xtext.ui.shared.xtextBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.xtext.ui.shared.xtextNature</nature> + </natures> +</projectDescription> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.code.compensator.model/META-INF/MANIFEST.MF new file mode 100644 index 000000000..3c1457770 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/META-INF/MANIFEST.MF @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.eclipse.fx.code.compensator.model;singleton:=true +Bundle-Version: 0.1.0.qualifier +Bundle-ClassPath: . +Bundle-Vendor: %providerName +Bundle-Localization: plugin +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Export-Package: org.eclipse.fx.code.compensator.model.workbench, + org.eclipse.fx.code.compensator.model.workbench.impl, + org.eclipse.fx.code.compensator.model.workbench.util +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.emf.ecore;visibility:=reexport, + org.eclipse.xtext.xbase.lib;resolution:=optional;visibility:=reexport, + org.eclipse.emf.ecore.xcore.lib;resolution:=optional;visibility:=reexport +Bundle-ActivationPolicy: lazy diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/build.properties b/experimental/compensator/org.eclipse.fx.code.compensator.model/build.properties new file mode 100644 index 000000000..697ca9645 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/build.properties @@ -0,0 +1,10 @@ +# + +bin.includes = .,\ + model/,\ + META-INF/,\ + plugin.xml,\ + plugin.properties +jars.compile.order = . +source.. = src-gen/ +output.. = bin/ diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/model/Workbench.xcore b/experimental/compensator/org.eclipse.fx.code.compensator.model/model/Workbench.xcore new file mode 100644 index 000000000..647d68c3f --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/model/Workbench.xcore @@ -0,0 +1,41 @@ +/******************************************************************************* +* Copyright (c) 2014 BestSolution.at and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation +*******************************************************************************/ +package org.eclipse.fx.code.compensator.model.workbench + +abstract class WorkbenchElement { + contains WorkbenchElement[0..*] elements + contains Resource[0..*] resources +} + +class Workbench extends WorkbenchElement { + +} + +abstract class Resource { + +} + +class File extends Resource { + String url +} + +class Folder extends Resource { + String url +} + +class ResourceGroup extends Resource { + String name + contains Resource[0..*] resources +} + +/*class Project extends Resource { + String url +}*/
\ No newline at end of file diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/plugin.properties b/experimental/compensator/org.eclipse.fx.code.compensator.model/plugin.properties new file mode 100644 index 000000000..ae615624d --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/plugin.properties @@ -0,0 +1,4 @@ +# + +pluginName = Workbench Model +providerName = www.example.org diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/plugin.xml b/experimental/compensator/org.eclipse.fx.code.compensator.model/plugin.xml new file mode 100644 index 000000000..c64319704 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/plugin.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.0"?> + +<!-- +--> + +<plugin> + + <extension point="org.eclipse.emf.ecore.generated_package"> + <!-- @generated Workbench --> + <package + uri="org.eclipse.fx.code.compensator.model.workbench" + class="org.eclipse.fx.code.compensator.model.workbench.WorkbenchPackage" + genModel="model/Workbench.xcore"/> + </extension> + +</plugin> diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/.gitignore new file mode 100644 index 000000000..1e98cf7ac --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/.gitignore @@ -0,0 +1,8 @@ +/File.java +/Folder.java +/Resource.java +/ResourceGroup.java +/Workbench.java +/WorkbenchElement.java +/WorkbenchFactory.java +/WorkbenchPackage.java diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/impl/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/impl/.gitignore new file mode 100644 index 000000000..bbca9eaff --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/impl/.gitignore @@ -0,0 +1,8 @@ +/FileImpl.java +/FolderImpl.java +/ResourceGroupImpl.java +/ResourceImpl.java +/WorkbenchElementImpl.java +/WorkbenchFactoryImpl.java +/WorkbenchImpl.java +/WorkbenchPackageImpl.java diff --git a/experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/util/.gitignore b/experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/util/.gitignore new file mode 100644 index 000000000..1d3804e90 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.code.compensator.model/src-gen/org/eclipse/fx/code/compensator/model/workbench/util/.gitignore @@ -0,0 +1,2 @@ +/WorkbenchAdapterFactory.java +/WorkbenchSwitch.java diff --git a/experimental/compensator/org.eclipse.fx.text.ui/.classpath b/experimental/compensator/org.eclipse.fx.text.ui/.classpath new file mode 100644 index 000000000..eca7bdba8 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/experimental/compensator/org.eclipse.fx.text.ui/.gitignore b/experimental/compensator/org.eclipse.fx.text.ui/.gitignore new file mode 100644 index 000000000..ae3c17260 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/experimental/compensator/org.eclipse.fx.text.ui/.project b/experimental/compensator/org.eclipse.fx.text.ui/.project new file mode 100644 index 000000000..817056f57 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.fx.text.ui</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/experimental/compensator/org.eclipse.fx.text.ui/.settings/org.eclipse.jdt.core.prefs b/experimental/compensator/org.eclipse.fx.text.ui/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..0c68a61dc --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/experimental/compensator/org.eclipse.fx.text.ui/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.text.ui/META-INF/MANIFEST.MF new file mode 100644 index 000000000..81fab4a9e --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/META-INF/MANIFEST.MF @@ -0,0 +1,50 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Ui +Bundle-SymbolicName: org.eclipse.fx.text.ui +Bundle-Version: 1.0.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Require-Bundle: org.eclipse.fx.ui.controls;bundle-version="1.0.0", + org.eclipse.text;bundle-version="3.5.300", + org.eclipse.fx.text;bundle-version="1.0.0" +Export-Package: org.eclipse.jface.text, + org.eclipse.jface.text.presentation, + org.eclipse.jface.text.reconciler, + org.eclipse.jface.text.rules, + org.eclipse.jface.text.source, + org.eclipse.jface.viewers +Import-Package: javafx.animation;version="2.2.0", + javafx.application;version="2.2.0", + javafx.beans;version="2.2.0", + javafx.beans.binding;version="2.2.0", + javafx.beans.property;version="2.2.0", + javafx.beans.property.adapter;version="2.2.0", + javafx.beans.value;version="2.2.0", + javafx.collections;version="2.2.0", + javafx.collections.transformation;version="8.0.0", + javafx.concurrent;version="2.2.0", + javafx.css;version="8.0.0", + javafx.embed.swing;version="2.2.0", + javafx.embed.swt;version="2.2.0", + javafx.event;version="2.2.0", + javafx.fxml;version="2.2.0", + javafx.geometry;version="2.2.0", + javafx.print;version="8.0.0", + javafx.scene;version="2.2.0", + javafx.scene.canvas;version="2.2.0", + javafx.scene.chart;version="2.2.0", + javafx.scene.control;version="2.2.0", + javafx.scene.control.cell;version="2.2.0", + javafx.scene.effect;version="2.2.0", + javafx.scene.image;version="2.2.0", + javafx.scene.input;version="2.2.0", + javafx.scene.layout;version="2.2.0", + javafx.scene.media;version="2.2.0", + javafx.scene.paint;version="2.2.0", + javafx.scene.shape;version="2.2.0", + javafx.scene.text;version="2.2.0", + javafx.scene.transform;version="2.2.0", + javafx.scene.web;version="2.2.0", + javafx.stage;version="2.2.0", + javafx.util;version="2.2.0", + javafx.util.converter;version="2.2.0" diff --git a/experimental/compensator/org.eclipse.fx.text.ui/build.properties b/experimental/compensator/org.eclipse.fx.text.ui/build.properties new file mode 100644 index 000000000..34d2e4d2d --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/DefaultDocumentAdapter.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/DefaultDocumentAdapter.java new file mode 100644 index 000000000..462db1fd5 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/DefaultDocumentAdapter.java @@ -0,0 +1,401 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text; + + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.fx.ui.controls.styledtext.TextChangedEvent; +import org.eclipse.fx.ui.controls.styledtext.TextChangingEvent; + + +/** + * Default implementation of {@link org.eclipse.jface.text.IDocumentAdapter}. + * <p> + * <strong>Note:</strong> This adapter does not work if the widget auto-wraps the text. + * </p> + */ +class DefaultDocumentAdapter implements IDocumentAdapter, IDocumentListener, IDocumentAdapterExtension { + + /** The adapted document. */ + private IDocument fDocument; + /** The document clone for the non-forwarding case. */ + private IDocument fDocumentClone; + /** The original content */ + private String fOriginalContent; + /** The original line delimiters */ + private String[] fOriginalLineDelimiters; + /** The registered text change listeners */ + private List fTextChangeListeners= new ArrayList(1); + /** + * The remembered document event + * @since 2.0 + */ + private DocumentEvent fEvent; + /** The line delimiter */ + private String fLineDelimiter= null; + /** + * Indicates whether this adapter is forwarding document changes + * @since 2.0 + */ + private boolean fIsForwarding= true; + /** + * Length of document at receipt of <code>documentAboutToBeChanged</code> + * @since 2.1 + */ + private int fRememberedLengthOfDocument; + /** + * Length of first document line at receipt of <code>documentAboutToBeChanged</code> + * @since 2.1 + */ + private int fRememberedLengthOfFirstLine; + /** + * The data of the event at receipt of <code>documentAboutToBeChanged</code> + * @since 2.1 + */ + private DocumentEvent fOriginalEvent= new DocumentEvent(); + + + /** + * Creates a new document adapter which is initially not connected to + * any document. + */ + public DefaultDocumentAdapter() { + } + + /** + * Sets the given document as the document to be adapted. + * + * @param document the document to be adapted or <code>null</code> if there is no document + */ + public void setDocument(IDocument document) { + + if (fDocument != null) + fDocument.removePrenotifiedDocumentListener(this); + + fDocument= document; + fLineDelimiter= null; + + if (!fIsForwarding) { + fDocumentClone= null; + if (fDocument != null) { + fOriginalContent= fDocument.get(); + fOriginalLineDelimiters= fDocument.getLegalLineDelimiters(); + } else { + fOriginalContent= null; + fOriginalLineDelimiters= null; + } + } + + if (fDocument != null) + fDocument.addPrenotifiedDocumentListener(this); + } + + /* + * @see StyledTextContent#addTextChangeListener(TextChangeListener) + */ + public void addTextChangeListener(TextChangeListener listener) { + Assert.isNotNull(listener); + if (!fTextChangeListeners.contains(listener)) + fTextChangeListeners.add(listener); + } + + /* + * @see StyledTextContent#removeTextChangeListener(TextChangeListener) + */ + public void removeTextChangeListener(TextChangeListener listener) { + Assert.isNotNull(listener); + fTextChangeListeners.remove(listener); + } + + /** + * Tries to repair the line information. + * + * @param document the document + * @see IRepairableDocument#repairLineInformation() + * @since 3.0 + */ + private void repairLineInformation(IDocument document) { + if (document instanceof IRepairableDocument) { + IRepairableDocument repairable= (IRepairableDocument) document; + repairable.repairLineInformation(); + } + } + + /** + * Returns the line for the given line number. + * + * @param document the document + * @param line the line number + * @return the content of the line of the given number in the given document + * @throws BadLocationException if the line number is invalid for the adapted document + * @since 3.0 + */ + private String doGetLine(IDocument document, int line) throws BadLocationException { + IRegion r= document.getLineInformation(line); + return document.get(r.getOffset(), r.getLength()); + } + + private IDocument getDocumentForRead() { + if (!fIsForwarding) { + if (fDocumentClone == null) { + String content= fOriginalContent == null ? "" : fOriginalContent; //$NON-NLS-1$ + String[] delims= fOriginalLineDelimiters == null ? DefaultLineTracker.DELIMITERS : fOriginalLineDelimiters; + fDocumentClone= new DocumentClone(content, delims); + } + return fDocumentClone; + } + + return fDocument; + } + + public String getLine(int line) { + + IDocument document= getDocumentForRead(); + try { + return doGetLine(document, line); + } catch (BadLocationException x) { + repairLineInformation(document); + try { + return doGetLine(document, line); + } catch (BadLocationException x2) { + } + } + + //TODO Log it + System.err.println("invalid argument"); + return null; + } + + public int getLineAtOffset(int offset) { + IDocument document= getDocumentForRead(); + try { + return document.getLineOfOffset(offset); + } catch (BadLocationException x) { + repairLineInformation(document); + try { + return document.getLineOfOffset(offset); + } catch (BadLocationException x2) { + } + } + + //TODO Log it + System.err.println("invalid argument"); + return -1; + } + + public int getLineCount() { + return getDocumentForRead().getNumberOfLines(); + } + + public int getOffsetAtLine(int line) { + IDocument document= getDocumentForRead(); + try { + return document.getLineOffset(line); + } catch (BadLocationException x) { + repairLineInformation(document); + try { + return document.getLineOffset(line); + } catch (BadLocationException x2) { + } + } + + //TODO Log it + System.err.println("invalid argument"); + return -1; + } + + public String getTextRange(int offset, int length) { + try { + return getDocumentForRead().get(offset, length); + } catch (BadLocationException x) { + //TODO Log it + x.printStackTrace(); + return null; + } + } + + public void replaceTextRange(int pos, int length, String text) { + try { + fDocument.replace(pos, length, text); + } catch (BadLocationException x) { + //TODO Log it + x.printStackTrace(); + } + } + + public void setText(String text) { + fDocument.set(text); + } + + /* + * @see StyledTextContent#getCharCount() + */ + public int getCharCount() { + return getDocumentForRead().getLength(); + } + + /* + * @see StyledTextContent#getLineDelimiter() + */ + public String getLineDelimiter() { + if (fLineDelimiter == null) + fLineDelimiter= TextUtilities.getDefaultLineDelimiter(fDocument); + return fLineDelimiter; + } + + /* + * @see IDocumentListener#documentChanged(DocumentEvent) + */ + public void documentChanged(DocumentEvent event) { + // check whether the given event is the one which was remembered + if (fEvent == null || event != fEvent) + return; + + if (isPatchedEvent(event) || (event.getOffset() == 0 && event.getLength() == fRememberedLengthOfDocument)) { + fLineDelimiter= null; + fireTextSet(); + } else { + if (event.getOffset() < fRememberedLengthOfFirstLine) + fLineDelimiter= null; + fireTextChanged(); + } + } + + /* + * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent) + */ + public void documentAboutToBeChanged(DocumentEvent event) { + + fRememberedLengthOfDocument= fDocument.getLength(); + try { + fRememberedLengthOfFirstLine= fDocument.getLineLength(0); + } catch (BadLocationException e) { + fRememberedLengthOfFirstLine= -1; + } + + fEvent= event; + rememberEventData(fEvent); + fireTextChanging(); + } + + /** + * Checks whether this event has been changed between <code>documentAboutToBeChanged</code> and + * <code>documentChanged</code>. + * + * @param event the event to be checked + * @return <code>true</code> if the event has been changed, <code>false</code> otherwise + */ + private boolean isPatchedEvent(DocumentEvent event) { + return fOriginalEvent.fOffset != event.fOffset || fOriginalEvent.fLength != event.fLength || fOriginalEvent.fText != event.fText; + } + + /** + * Makes a copy of the given event and remembers it. + * + * @param event the event to be copied + */ + private void rememberEventData(DocumentEvent event) { + fOriginalEvent.fOffset= event.fOffset; + fOriginalEvent.fLength= event.fLength; + fOriginalEvent.fText= event.fText; + } + + /** + * Sends a text changed event to all registered listeners. + */ + private void fireTextChanged() { + + if (!fIsForwarding) + return; + + TextChangedEvent event = TextChangedEvent.textChanged(this); + + if (fTextChangeListeners != null && fTextChangeListeners.size() > 0) { + Iterator e= new ArrayList(fTextChangeListeners).iterator(); + while (e.hasNext()) + ((TextChangeListener) e.next()).textChanged(event); + } + } + + /** + * Sends a text set event to all registered listeners. + */ + private void fireTextSet() { + + if (!fIsForwarding) + return; + + TextChangedEvent event = TextChangedEvent.textSet(this); + + if (fTextChangeListeners != null && fTextChangeListeners.size() > 0) { + Iterator e= new ArrayList(fTextChangeListeners).iterator(); + while (e.hasNext()) + ((TextChangeListener) e.next()).textSet(event); + } + } + + /** + * Sends the text changing event to all registered listeners. + */ + private void fireTextChanging() { + + if (!fIsForwarding) + return; + + try { + IDocument document= fEvent.getDocument(); + if (document == null) + return; + + TextChangingEvent event= TextChangingEvent.textChanging(this, + fEvent.fOffset, + fEvent.fLength, + document.getNumberOfLines(fEvent.fOffset, fEvent.fLength) - 1, + fEvent.fText, + (fEvent.fText == null ? 0 : fEvent.fText.length()), + (fEvent.fText == null ? 0 : document.computeNumberOfLines(fEvent.fText))); + + if (fTextChangeListeners != null && fTextChangeListeners.size() > 0) { + Iterator e= new ArrayList(fTextChangeListeners).iterator(); + while (e.hasNext()) + ((TextChangeListener) e.next()).textChanging(event); + } + + } catch (BadLocationException e) { + } + } + + /* + * @see IDocumentAdapterExtension#resumeForwardingDocumentChanges() + * @since 2.0 + */ + public void resumeForwardingDocumentChanges() { + fIsForwarding= true; + fDocumentClone= null; + fOriginalContent= null; + fOriginalLineDelimiters= null; + fireTextSet(); + } + + /* + * @see IDocumentAdapterExtension#stopForwardingDocumentChanges() + * @since 2.0 + */ + public void stopForwardingDocumentChanges() { + fDocumentClone= null; + fOriginalContent= fDocument.get(); + fOriginalLineDelimiters= fDocument.getLegalLineDelimiters(); + fIsForwarding= false; + } +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IDocumentAdapter.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IDocumentAdapter.java new file mode 100644 index 000000000..55a9b094b --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IDocumentAdapter.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text; + +import org.eclipse.fx.ui.controls.styledtext.StyledTextContent; + + +/** + * Adapts an {@link org.eclipse.jface.text.IDocument}to the + * {@link org.eclipse.swt.custom.StyledTextContent} interface. The document + * adapter is used by {@link org.eclipse.jface.text.TextViewer} to translate + * document changes into styled text content changes and vice versa. + * <p> + * Clients may implement this interface and override + * <code>TextViewer.createDocumentAdapter</code> if they want to intercept the + * communication between the viewer's text widget and the viewer's document. + * <p> + * In order to provide backward compatibility for clients of + * <code>IDocumentAdapter</code>, extension interfaces are used as a means of + * evolution. The following extension interfaces exist: + * <ul> + * <li>{@link org.eclipse.jface.text.IDocumentAdapterExtension} since version + * 2.0 introducing a way of batching a sequence of document changes into a + * single styled text content notification</li> + * </ul> + * + * @see org.eclipse.jface.text.IDocumentAdapterExtension + * @see org.eclipse.jface.text.IDocument + */ +public interface IDocumentAdapter extends StyledTextContent { + + /** + * Sets the adapters document. + * + * @param document the document to be adapted + */ + void setDocument(IDocument document); +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IDocumentAdapterExtension.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IDocumentAdapterExtension.java new file mode 100644 index 000000000..160ee3e40 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IDocumentAdapterExtension.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.jface.text; + +/** + * Extension interface for {@link org.eclipse.jface.text.IDocumentAdapter}. + * <p> + * Introduces the concepts of batching a series of document changes into a + * single styled text content change notification. Batching start when a client + * calls <code>stopForwardingDocumentChanges</code>. After that call this + * document adapter does not send out styled text content change notifications + * until <code>resumeForwardingDocumentChanges</code> is called. On + * <code>resumeForwardingDocumentChanges</code>, it sends out one styled text + * content change notification that covers all changes that have been applied to + * the document since calling <code>stopForwardingDocumentChanges</code>. + * + * @since 2.0 + */ +public interface IDocumentAdapterExtension { + + /** + * Stops forwarding document changes to the styled text. + */ + void stopForwardingDocumentChanges(); + + /** + * Resumes forwarding document changes to the styled text. + * Also forces the styled text to catch up with all the changes + * that have been applied since <code>stopForwardingDocumentChanges</code> + * has been called. + */ + void resumeForwardingDocumentChanges(); +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IRewriteTarget.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IRewriteTarget.java new file mode 100644 index 000000000..0f698dc77 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/IRewriteTarget.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text; + + + /** + * A target publishing the required functions to modify a document that is displayed + * in a text viewer. It provides access to the document and control + * over the redraw behavior and the grouping of document changes into undo commands. + * + * @see org.eclipse.jface.text.ITextViewer + * @see org.eclipse.jface.text.IDocument + * @see org.eclipse.jface.text.IUndoManager + * @since 2.0 + */ +public interface IRewriteTarget { + + /** + * Returns the document of this target. + * + * @return the document of this target + */ + IDocument getDocument(); + + /** + * Disables/enables redrawing while modifying the target's document. + * + * @param redraw <code>true</code> if the document's visible presentation + * should be updated, <code>false</code> otherwise + */ + void setRedraw(boolean redraw); + + /** + * If an undo manager is connected to the document's visible presentation, + * this method tells the undo manager to fold all subsequent changes into + * one single undo command until <code>endCompoundChange</code> is called. + */ + void beginCompoundChange(); + + /** + * If an undo manager is connected to the document's visible presentation, + * this method tells the undo manager to stop the folding of changes into a + * single undo command. After this call, all subsequent changes are + * considered to be individually undo-able. + */ + void endCompoundChange(); +} + diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextInputListener.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextInputListener.java new file mode 100644 index 000000000..44f6d3739 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextInputListener.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text; + + + +/** + * Text input listeners registered with an + * {@link org.eclipse.jface.text.ITextViewer} are informed if the document + * serving as the text viewer's model is replaced. + * <p> + * Clients may implement this interface.</p> + * + * @see org.eclipse.jface.text.ITextViewer + * @see org.eclipse.jface.text.IDocument + */ +public interface ITextInputListener { + + /** + * Called before the input document is replaced. + * + * @param oldInput the text viewer's previous input document + * @param newInput the text viewer's new input document + */ + void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput); + + /** + * Called after the input document has been replaced. + * + * @param oldInput the text viewer's previous input document + * @param newInput the text viewer's new input document + */ + void inputDocumentChanged(IDocument oldInput, IDocument newInput); +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextListener.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextListener.java new file mode 100644 index 000000000..64d944166 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextListener.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2000, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text; + + + +/** + * Text listeners registered with a text viewer are informed about all + * modifications of an {@link org.eclipse.jface.text.ITextViewer} by means of + * text events. A text event describes a change as a replace operation. + * <p> + * The changes described in the event are the changes applied to the text + * viewer's widget (i.e., its visual representation) and not those applied to the + * text viewer's document. The text event can be asked to return the + * corresponding document event. If the text event does not contain a document + * event, the modification of the text viewer is a presentation change. For + * example, changing the visible region of a text viewer, is a presentation + * change. A completely empty text event represents a change of the viewer's + * redraw state.</p> + * <p> + * If a text listener receives a text event, it is guaranteed that both the + * document and the viewer's visual representation are synchronized.</p> + * <p> + * Clients may implement this interface.</p> + * + * @see org.eclipse.jface.text.ITextViewer + * @see org.eclipse.jface.text.TextEvent + * @see org.eclipse.jface.text.DocumentEvent + */ +public interface ITextListener { + + /** + * The visual representation of a text viewer this listener is registered with + * has been changed. + * + * @param event the description of the change + */ + void textChanged(TextEvent event); +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextPresentationListener.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextPresentationListener.java new file mode 100644 index 000000000..839c87477 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextPresentationListener.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text; + + +/** + * Text presentation listeners registered with an + * {@link org.eclipse.jface.text.ITextViewer} are informed when a + * {@link org.eclipse.jface.text.TextPresentation} is about to be applied to the + * text viewer. The listener can apply changes to the text presentation and thus + * participate in the process of text presentation creation. + * + * @since 3.0 + */ +public interface ITextPresentationListener { + + /** + * This method is called when a text presentation is about to be applied to + * the text viewer. The receiver is allowed to change the text presentation + * during that call. + * + * @param textPresentation the current text presentation + */ + public void applyTextPresentation(TextPresentation textPresentation); +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewer.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewer.java new file mode 100644 index 000000000..5508c2ac4 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewer.java @@ -0,0 +1,12 @@ +package org.eclipse.jface.text; + +public interface ITextViewer { + public IDocument getDocument(); + public void setDocument(IDocument document); + public IRegion getVisibleRegion(); + void addTextListener(ITextListener listener); + public void removeTextListener(ITextListener listener); + void addTextInputListener(ITextInputListener listener); + void removeTextInputListener(ITextInputListener listener); + void changeTextPresentation(TextPresentation presentation, boolean controlRedraw); +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension.java new file mode 100644 index 000000000..ab8ff8b3d --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension.java @@ -0,0 +1,5 @@ +package org.eclipse.jface.text; + +public interface ITextViewerExtension { + +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension2.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension2.java new file mode 100644 index 000000000..80730e025 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension2.java @@ -0,0 +1,5 @@ +package org.eclipse.jface.text; + +public interface ITextViewerExtension2 { + +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension3.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension3.java new file mode 100644 index 000000000..82adc0d3f --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension3.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text; + + +/** + * Extension interface for {@link org.eclipse.jface.text.ITextViewer}. <p> + * This interface has been replaced by {@link org.eclipse.jface.text.ITextViewerExtension5}. + * Clients are not supposed to use this interface any longer. + * + * @since 2.1 + * @deprecated replaced by {@link org.eclipse.jface.text.ITextViewerExtension5} + */ +public interface ITextViewerExtension3 { + + + /** + * Returns the minimal region of the viewer's document that completely comprises everything that is + * visible in the viewer's widget or <code>null</code> if there is no such region. + * + * @return the minimal region of the viewer's document comprising the contents of the viewer's widget or <code>null</code> + */ + IRegion getModelCoverage(); + + + /** + * Returns the widget line that corresponds to the given line of the viewer's document or <code>-1</code> if there is no such line. + * + * @param modelLine the line of the viewer's document + * @return the corresponding widget line or <code>-1</code> + */ + int modelLine2WidgetLine(int modelLine); + + /** + * Returns the widget offset that corresponds to the given offset in the viewer's document + * or <code>-1</code> if there is no such offset + * + * @param modelOffset the offset in the viewer's document + * @return the corresponding widget offset or <code>-1</code> + */ + int modelOffset2WidgetOffset(int modelOffset); + + /** + * Returns the minimal region of the viewer's widget that completely comprises the given region of the + * viewer's document or <code>null</code> if there is no such region. + * + * @param modelRange the region of the viewer's document + * @return the minimal region of the widget comprising <code>modelRange</code> or <code>null</code> + */ + IRegion modelRange2WidgetRange(IRegion modelRange); + + + /** + * Returns the offset of the viewer's document that corresponds to the given widget offset + * or <code>-1</code> if there is no such offset + * + * @param widgetOffset the widget offset + * @return the corresponding offset in the viewer's document or <code>-1</code> + */ + int widgetOffset2ModelOffset(int widgetOffset); + + /** + * Returns the minimal region of the viewer's document that completely comprises the given widget region + * or <code>null</code> if there is no such region. + * + * @param widgetRange the widget region + * @return the minimal region of the viewer's document comprising <code>widgetRange</code> or <code>null</code> + */ + IRegion widgetRange2ModelRange(IRegion widgetRange); + + /** + * Returns the line of the viewer's document that corresponds to the given widget line or <code>-1</code> if there is no such line. + * + * @param widgetLine the widget line + * @return the corresponding line of the viewer's document or <code>-1</code> + */ + int widgetlLine2ModelLine(int widgetLine); + + /** + * Returns the widget line of the given widget offset. + * + * @param widgetOffset the widget offset + * @return the widget line of the widget offset + */ + int widgetLineOfWidgetOffset(int widgetOffset); +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension4.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension4.java new file mode 100644 index 000000000..e04cb953b --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension4.java @@ -0,0 +1,5 @@ +package org.eclipse.jface.text; + +public interface ITextViewerExtension4 { + +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension5.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension5.java new file mode 100644 index 000000000..206cfc3ce --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension5.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text; + +/** + * Extension interface for {@link org.eclipse.jface.text.ITextViewer}. Defines + * a conceptual replacement of the original visible region concept. This interface + * replaces {@link org.eclipse.jface.text.ITextViewerExtension3}. + * <p> + * Introduces the explicit concept of model and widget coordinates. For example, + * a selection returned by the text viewer's control is a widget selection. A + * widget selection always maps to a certain range of the viewer's document. + * This range is considered the model selection. + * <p> + * All model ranges that have a corresponding widget ranges are considered + * "exposed model ranges". The viewer can be requested to expose a given model + * range. Thus, a visible region is a particular degeneration of exposed model + * ranges. + * <p> + * This interface allows implementers to follow a sophisticated presentation + * model in which the visible presentation is a complex projection of the + * viewer's input document. + * + * @since 3.0 + */ +public interface ITextViewerExtension5 extends ITextViewerExtension3 { + + /** + * Returns the minimal region of the viewer's input document that completely + * comprises everything that is visible in the viewer's widget or + * <code>null</code> if there is no such region. + * + * @return the minimal region of the viewer's document comprising the + * contents of the viewer's widget or <code>null</code> + */ + IRegion getModelCoverage(); + + /** + * Returns the widget line that corresponds to the given line of the + * viewer's input document or <code>-1</code> if there is no such line. + * + * @param modelLine the line of the viewer's document + * @return the corresponding widget line or <code>-1</code> + */ + int modelLine2WidgetLine(int modelLine); + + /** + * Returns the widget offset that corresponds to the given offset in the + * viewer's input document or <code>-1</code> if there is no such offset + * + * @param modelOffset the offset in the viewer's document + * @return the corresponding widget offset or <code>-1</code> + */ + int modelOffset2WidgetOffset(int modelOffset); + + /** + * Returns the minimal region of the viewer's widget that completely + * comprises the given region of the viewer's input document or + * <code>null</code> if there is no such region. + * + * @param modelRange the region of the viewer's document + * @return the minimal region of the widget comprising + * <code>modelRange</code> or <code>null</code> + */ + IRegion modelRange2WidgetRange(IRegion modelRange); + + /** + * Returns the offset of the viewer's input document that corresponds to the + * given widget offset or <code>-1</code> if there is no such offset + * + * @param widgetOffset the widget offset + * @return the corresponding offset in the viewer's document or + * <code>-1</code> + */ + int widgetOffset2ModelOffset(int widgetOffset); + + /** + * Returns the minimal region of the viewer's input document that completely + * comprises the given widget region or <code>null</code> if there is no + * such region. + * + * @param widgetRange the widget region + * @return the minimal region of the viewer's document comprising + * <code>widgetlRange</code> or <code>null</code> + */ + IRegion widgetRange2ModelRange(IRegion widgetRange); + + /** + * Returns the line of the viewer's input document that corresponds to the + * given widget line or <code>-1</code> if there is no such line. + * + * @param widgetLine the widget line + * @return the corresponding line of the viewer's document or + * <code>-1</code> + */ + int widgetLine2ModelLine(int widgetLine); + + /** + * Returns the widget line of the given widget offset. + * + * @param widgetOffset the widget offset + * @return the widget line of the widget offset + */ + int widgetLineOfWidgetOffset(int widgetOffset); + + + /** + * Returns the maximal subranges of the given model range thus that there is + * no offset inside a subrange for which there is no image offset. + * + * @param modelRange the model range + * @return the list of subranges + */ + IRegion[] getCoveredModelRanges(IRegion modelRange); + + /** + * Exposes the given model range. Returns whether this call caused a change + * of the set of exposed model ranges. + * + * @param modelRange the model range to be exposed + * @return <code>true</code> if the set of exposed model ranges changed, + * <code>false</code> otherwise + */ + boolean exposeModelRange(IRegion modelRange); +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension6.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension6.java new file mode 100644 index 000000000..9024869b6 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension6.java @@ -0,0 +1,5 @@ +package org.eclipse.jface.text; + +public interface ITextViewerExtension6 { + +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension7.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension7.java new file mode 100644 index 000000000..4cf21ff40 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension7.java @@ -0,0 +1,5 @@ +package org.eclipse.jface.text; + +public interface ITextViewerExtension7 { + +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension8.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension8.java new file mode 100644 index 000000000..bb4b986f7 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/ITextViewerExtension8.java @@ -0,0 +1,5 @@ +package org.eclipse.jface.text; + +public interface ITextViewerExtension8 { + +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextAttribute.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextAttribute.java new file mode 100644 index 000000000..573183899 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextAttribute.java @@ -0,0 +1,182 @@ +/******************************************************************************* + * Copyright (c) 2000, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text; + +import org.eclipse.fx.ui.controls.styledtext.StyleRange; + +import javafx.scene.paint.Color; +import javafx.scene.text.Font; + + +/** + * Description of textual attributes such as color and style. Text attributes + * are considered value objects. + * <p> + * Clients usually instantiate object of the class.</p> + */ +public class TextAttribute { + + /** + * Text attribute for strikethrough style. + * (value <code>1 << 29</code>). + * @since 3.1 + */ + public static final int STRIKETHROUGH= 1 << 29; + + /** + * Text attribute for underline style. + * (value <code>1 << 30</code>) + * @since 3.1 + */ + public static final int UNDERLINE= 1 << 30; + + + /** Foreground color */ + private Color foreground; + + /** Background color */ + private Color background; + + /** The text style */ + private int style; + + /** + * The text font. + * @since 3.3 + */ + private Font font; + + /** + * Cached hash code. + * @since 3.3 + */ + private int fHashCode; + + /** + * Creates a text attribute with the given colors and style. + * + * @param foreground the foreground color, <code>null</code> if none + * @param background the background color, <code>null</code> if none + * @param style the style + */ + public TextAttribute(Color foreground, Color background, int style) { + this.foreground= foreground; + this.background= background; + this.style= style; + } + + /** + * Creates a text attribute with the given colors and style. + * + * @param foreground the foreground color, <code>null</code> if none + * @param background the background color, <code>null</code> if none + * @param style the style + * @param font the font, <code>null</code> if none + * @since 3.3 + */ + public TextAttribute(Color foreground, Color background, int style, Font font) { + this.foreground= foreground; + this.background= background; + this.style= style; + this.font= font; + } + + /** + * Creates a text attribute for the given foreground color, no background color and + * with the SWT normal style. + * + * @param foreground the foreground color, <code>null</code> if none + */ + public TextAttribute(Color foreground) { + this(foreground, null, StyleRange.NORMAL); + } + + /* + * @see Object#equals(Object) + */ + public boolean equals(Object object) { + + if (object == this) + return true; + + if (!(object instanceof TextAttribute)) + return false; + TextAttribute a= (TextAttribute)object; + + return (a.style == style && equals(a.foreground, foreground) && equals(a.background, background) && equals(a.font, font)); + } + + /** + * Returns whether the two given objects are equal. + * + * @param o1 the first object, can be <code>null</code> + * @param o2 the second object, can be <code>null</code> + * @return <code>true</code> if the given objects are equals + * @since 2.0 + */ + private boolean equals(Object o1, Object o2) { + if (o1 != null) + return o1.equals(o2); + return (o2 == null); + } + + /* + * @see Object#hashCode() + */ + public int hashCode() { + if (fHashCode == 0) { + int multiplier= 37; // some prime + fHashCode= 13; // some random value + fHashCode= multiplier * fHashCode + (font == null ? 0 : font.hashCode()); + fHashCode= multiplier * fHashCode + (background == null ? 0 : background.hashCode()); + fHashCode= multiplier * fHashCode + (foreground == null ? 0 : foreground.hashCode()); + fHashCode= multiplier * fHashCode + style; + } + return fHashCode; + } + + /** + * Returns the attribute's foreground color. + * + * @return the attribute's foreground color or <code>null</code> if not set + */ + public Color getForeground() { + return foreground; + } + + /** + * Returns the attribute's background color. + * + * @return the attribute's background color or <code>null</code> if not set + */ + public Color getBackground() { + return background; + } + + /** + * Returns the attribute's style. + * + * @return the attribute's style + */ + public int getStyle() { + return style; + } + + /** + * Returns the attribute's font. + * + * @return the attribute's font or <code>null</code> if not set + * @since 3.3 + */ + public Font getFont() { + return font; + } +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextEvent.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextEvent.java new file mode 100644 index 000000000..617d0e23e --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextEvent.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text; + + +/** + * This event is sent to implementers of + * {@link org.eclipse.jface.text.ITextListener}. It represents a change applied + * to text viewer. The change is specified as a replace command using offset, + * length, inserted text, and replaced text. The text viewer issues a text event + * after the viewer has been changed either in response to a change of the + * viewer's document or when the viewer's visual content has been changed. In + * the first case, the text event also carries the original document event. + * Depending on the viewer's presentation mode, the text event coordinates are + * different from the document event's coordinates. + * <p> + * An empty text event usually indicates a change of the viewer's redraw state.</p> + * <p> + * Clients other than text viewer's don't create instances of this class.</p> + * + * @see org.eclipse.jface.text.ITextListener + * @see org.eclipse.jface.text.ITextViewer + * @see org.eclipse.jface.text.DocumentEvent + */ +public class TextEvent { + + /** Start offset of the change */ + private int fOffset; + /** The length of the change */ + private int fLength; + /** Inserted text */ + private String fText; + /** Replaced text */ + private String fReplacedText; + /** The original document event, may by null */ + private DocumentEvent fDocumentEvent; + /** + * The redraw state of the viewer issuing this event + * @since 2.0 + */ + private boolean fViewerRedrawState; + + /** + * Creates a new <code>TextEvent</code> based on the specification. + * + * @param offset the offset + * @param length the length + * @param text the inserted text + * @param replacedText the replaced text + * @param event the associated document event or <code>null</code> if none + * @param viewerRedrawState the redraw state of the viewer + */ + protected TextEvent(int offset, int length, String text, String replacedText, DocumentEvent event, boolean viewerRedrawState) { + fOffset= offset; + fLength= length; + fText= text; + fReplacedText= replacedText; + fDocumentEvent= event; + fViewerRedrawState= viewerRedrawState; + } + + /** + * Returns the offset of the event. + * + * @return the offset of the event + */ + public int getOffset() { + return fOffset; + } + + /** + * Returns the length of the event. + * + * @return the length of the event + */ + public int getLength() { + return fLength; + } + + /** + * Returns the text of the event. + * + * @return the text of the event + */ + public String getText() { + return fText; + } + + /** + * Returns the text replaced by this event. + * + * @return the text replaced by this event + */ + public String getReplacedText() { + return fReplacedText; + } + + /** + * Returns the corresponding document event that caused the viewer change + * + * @return the corresponding document event, <code>null</code> if a visual change only + */ + public DocumentEvent getDocumentEvent() { + return fDocumentEvent; + } + + /** + * Returns the viewer's redraw state. + * + * @return <code>true</code> if the viewer's redraw state is <code>true</code> + * @since 2.0 + */ + public boolean getViewerRedrawState() { + return fViewerRedrawState; + } +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextPresentation.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextPresentation.java new file mode 100644 index 000000000..92b982f80 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextPresentation.java @@ -0,0 +1,731 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.NoSuchElementException; + +import org.eclipse.fx.ui.controls.styledtext.StyleRange; +import org.eclipse.fx.ui.controls.styledtext.StyledTextArea; + + +/** + * Describes the presentation styles for a section of an indexed text such as a + * document or string. A text presentation defines a default style for the whole + * section and in addition style differences for individual subsections. Text + * presentations can be narrowed down to a particular result window. All methods + * are result window aware, i.e. ranges outside the result window are always + * ignored. + * <p> + * All iterators provided by a text presentation assume that they enumerate non + * overlapping, consecutive ranges inside the default range. Thus, all these + * iterators do not include the default range. The default style range must be + * explicitly asked for using <code>getDefaultStyleRange</code>. + */ +public class TextPresentation { + + /** + * Applies the given presentation to the given text widget. Helper method. + * + * @param presentation the style information + * @param text the widget to which to apply the style information + * @since 2.0 + */ + public static void applyTextPresentation(TextPresentation presentation, StyledTextArea text) { + + StyleRange[] ranges= new StyleRange[presentation.getDenumerableRanges()]; + + int i= 0; + Iterator e= presentation.getAllStyleRangeIterator(); + while (e.hasNext()) + ranges[i++]= (StyleRange) e.next(); + + text.setStyleRanges(ranges); + } + + + + + /** + * Enumerates all the <code>StyleRange</code>s included in the presentation. + */ + class FilterIterator implements Iterator { + + /** The index of the next style range to be enumerated */ + protected int fIndex; + /** The upper bound of the indices of style ranges to be enumerated */ + protected int fLength; + /** Indicates whether ranges similar to the default range should be enumerated */ + protected boolean fSkipDefaults; + /** The result window */ + protected IRegion fWindow; + + /** + * <code>skipDefaults</code> tells the enumeration to skip all those style ranges + * which define the same style as the presentation's default style range. + * + * @param skipDefaults <code>false</code> if ranges similar to the default range should be enumerated + */ + protected FilterIterator(boolean skipDefaults) { + + fSkipDefaults= skipDefaults; + + fWindow= fResultWindow; + fIndex= getFirstIndexInWindow(fWindow); + fLength= getFirstIndexAfterWindow(fWindow); + + if (fSkipDefaults) + computeIndex(); + } + + /* + * @see Iterator#next() + */ + public Object next() { + try { + StyleRange r= (StyleRange) fRanges.get(fIndex++); + return createWindowRelativeRange(fWindow, r); + } catch (ArrayIndexOutOfBoundsException x) { + throw new NoSuchElementException(); + } finally { + if (fSkipDefaults) + computeIndex(); + } + } + + /* + * @see Iterator#hasNext() + */ + public boolean hasNext() { + return fIndex < fLength; + } + + /* + * @see Iterator#remove() + */ + public void remove() { + throw new UnsupportedOperationException(); + } + + /** + * Returns whether the given object should be skipped. + * + * @param o the object to be checked + * @return <code>true</code> if the object should be skipped by the iterator + */ + protected boolean skip(Object o) { + StyleRange r= (StyleRange) o; + return r.similarTo(fDefaultRange); + } + + /** + * Computes the index of the styled range that is the next to be enumerated. + */ + protected void computeIndex() { + while (fIndex < fLength && skip(fRanges.get(fIndex))) + ++ fIndex; + } + } + + /** The style information for the range covered by the whole presentation */ + private StyleRange fDefaultRange; + /** The member ranges of the presentation */ + private ArrayList fRanges; + /** A clipping region against which the presentation can be clipped when asked for results */ + private IRegion fResultWindow; + /** + * The optional extent for this presentation. + * @since 3.0 + */ + private IRegion fExtent; + + + /** + * Creates a new empty text presentation. + */ + public TextPresentation() { + fRanges= new ArrayList(50); + } + + /** + * Creates a new empty text presentation. <code>sizeHint</code> tells the expected size of this + * presentation. + * + * @param sizeHint the expected size of this presentation, must be positive + */ + public TextPresentation(int sizeHint) { + Assert.isTrue(sizeHint > 0); + fRanges= new ArrayList(sizeHint); + } + + /** + * Creates a new empty text presentation with the given extent. <code>sizeHint</code> tells the + * expected size of this presentation. + * + * @param extent the extent of the created <code>TextPresentation</code> + * @param sizeHint the expected size of this presentation, must be positive + * @since 3.0 + */ + public TextPresentation(IRegion extent, int sizeHint) { + this(sizeHint); + Assert.isNotNull(extent); + fExtent= extent; + } + + /** + * Sets the result window for this presentation. When dealing with + * this presentation all ranges which are outside the result window + * are ignored. For example, the size of the presentation is 0 + * when there is no range inside the window even if there are ranges + * outside the window. All methods are aware of the result window. + * + * @param resultWindow the result window + */ + public void setResultWindow(IRegion resultWindow) { + fResultWindow= resultWindow; + } + + /** + * Set the default style range of this presentation. + * The default style range defines the overall area covered + * by this presentation and its style information. + * + * @param range the range describing the default region + */ + public void setDefaultStyleRange(StyleRange range) { + fDefaultRange= range; + } + + /** + * Returns this presentation's default style range. The returned <code>StyleRange</code> + * is relative to the start of the result window. + * + * @return this presentation's default style range + */ + public StyleRange getDefaultStyleRange() { + StyleRange range= createWindowRelativeRange(fResultWindow, fDefaultRange); + if (range == null) + return null; + return (StyleRange)range.clone(); + + } + + /** + * Add the given range to the presentation. The range must be a + * subrange of the presentation's default range. + * + * @param range the range to be added + */ + public void addStyleRange(StyleRange range) { + checkConsistency(range); + fRanges.add(range); + } + + /** + * Replaces the given range in this presentation. The range must be a + * subrange of the presentation's default range. + * + * @param range the range to be added + * @since 3.0 + */ + public void replaceStyleRange(StyleRange range) { + applyStyleRange(range, false); + } + + /** + * Merges the given range into this presentation. The range must be a + * subrange of the presentation's default range. + * + * @param range the range to be added + * @since 3.0 + */ + public void mergeStyleRange(StyleRange range) { + applyStyleRange(range, true); + } + + /** + * Applies the given range to this presentation. The range must be a + * subrange of the presentation's default range. + * + * @param range the range to be added + * @param merge <code>true</code> if the style should be merged instead of replaced + * @since 3.0 + */ + private void applyStyleRange(StyleRange range, boolean merge) { + if (range.length == 0) + return; + + checkConsistency(range); + + int start= range.start; + int length= range.length; + int end= start + length; + + if (fRanges.size() == 0) { + StyleRange defaultRange= getDefaultStyleRange(); + if (defaultRange == null) + defaultRange= range; + + defaultRange.start= start; + defaultRange.length= length; + applyStyle(range, defaultRange, merge); + fRanges.add(defaultRange); + } else { + IRegion rangeRegion= new Region(start, length); + int first= getFirstIndexInWindow(rangeRegion); + + if (first == fRanges.size()) { + StyleRange defaultRange= getDefaultStyleRange(); + if (defaultRange == null) + defaultRange= range; + defaultRange.start= start; + defaultRange.length= length; + applyStyle(range, defaultRange, merge); + fRanges.add(defaultRange); + return; + } + + int last= getFirstIndexAfterWindow(rangeRegion); + for (int i= first; i < last && length > 0; i++) { + + StyleRange current= (StyleRange)fRanges.get(i); + int currentStart= current.start; + int currentEnd= currentStart + current.length; + + if (end <= currentStart) { + fRanges.add(i, range); + return; + } + + if (start >= currentEnd) + continue; + + StyleRange currentCopy= null; + if (end < currentEnd) + currentCopy= (StyleRange)current.clone(); + + if (start < currentStart) { + // Apply style to new default range and add it + StyleRange defaultRange= getDefaultStyleRange(); + if (defaultRange == null) + defaultRange= new StyleRange(); + + defaultRange.start= start; + defaultRange.length= currentStart - start; + applyStyle(range, defaultRange, merge); + fRanges.add(i, defaultRange); + i++; last++; + + + // Apply style to first part of current range + current.length= Math.min(end, currentEnd) - currentStart; + applyStyle(range, current, merge); + } + + if (start >= currentStart) { + // Shorten the current range + current.length= start - currentStart; + + // Apply the style to the rest of the current range and add it + if (current.length > 0) { + current= (StyleRange)current.clone(); + i++; last++; + fRanges.add(i, current); + } + applyStyle(range, current, merge); + current.start= start; + current.length= Math.min(end, currentEnd) - start; + } + + if (end < currentEnd) { + // Add rest of current range + currentCopy.start= end; + currentCopy.length= currentEnd - end; + i++; last++; + fRanges.add(i, currentCopy); + } + + // Update range + range.start= currentEnd; + range.length= Math.max(end - currentEnd, 0); + start= range.start; + length= range.length; + } + if (length > 0) { + // Apply style to new default range and add it + StyleRange defaultRange= getDefaultStyleRange(); + if (defaultRange == null) + defaultRange= range; + defaultRange.start= start; + defaultRange.length= end - start; + applyStyle(range, defaultRange, merge); + fRanges.add(last, defaultRange); + } + } + } + + /** + * Replaces the given ranges in this presentation. Each range must be a + * subrange of the presentation's default range. The ranges must be ordered + * by increasing offset and must not overlap (but may be adjacent). + * + * @param ranges the ranges to be added + * @since 3.0 + */ + public void replaceStyleRanges(StyleRange[] ranges) { + applyStyleRanges(ranges, false); + } + + /** + * Merges the given ranges into this presentation. Each range must be a + * subrange of the presentation's default range. The ranges must be ordered + * by increasing offset and must not overlap (but may be adjacent). + * + * @param ranges the ranges to be added + * @since 3.0 + */ + public void mergeStyleRanges(StyleRange[] ranges) { + applyStyleRanges(ranges, true); + } + + /** + * Applies the given ranges to this presentation. Each range must be a + * subrange of the presentation's default range. The ranges must be ordered + * by increasing offset and must not overlap (but may be adjacent). + * + * @param ranges the ranges to be added + * @param merge <code>true</code> if the style should be merged instead of replaced + * @since 3.0 + */ + private void applyStyleRanges(StyleRange[] ranges, boolean merge) { + int j= 0; + ArrayList oldRanges= fRanges; + ArrayList newRanges= new ArrayList(2*ranges.length + oldRanges.size()); + for (int i= 0, n= ranges.length; i < n; i++) { + StyleRange range= ranges[i]; + fRanges= oldRanges; // for getFirstIndexAfterWindow(...) + for (int m= getFirstIndexAfterWindow(new Region(range.start, range.length)); j < m; j++) + newRanges.add(oldRanges.get(j)); + fRanges= newRanges; // for mergeStyleRange(...) + applyStyleRange(range, merge); + } + for (int m= oldRanges.size(); j < m; j++) + newRanges.add(oldRanges.get(j)); + fRanges= newRanges; + } + + /** + * Applies the template's style to the target. + * + * @param template the style range to be used as template + * @param target the style range to which to apply the template + * @param merge <code>true</code> if the style should be merged instead of replaced + * @since 3.0 + */ + private void applyStyle(StyleRange template, StyleRange target, boolean merge) { + if (merge) { + if (template.font != null) + target.font= template.font; + target.fontStyle|= template.fontStyle; + +//TODO No metrics +// if (template.metrics != null) +// target.metrics= template.metrics; + + if (template.foreground != null || template.underlineStyle == StyleRange.UNDERLINE_LINK) + target.foreground= template.foreground; + if (template.background != null) + target.background= template.background; + + target.strikeout|= template.strikeout; + if (template.strikeoutColor != null) + target.strikeoutColor= template.strikeoutColor; + + target.underline|= template.underline; + if (template.underlineStyle != StyleRange.NONE && target.underlineStyle != StyleRange.UNDERLINE_LINK) + target.underlineStyle= template.underlineStyle; + + if (template.underlineColor != null) + target.underlineColor= template.underlineColor; + + if (template.borderStyle != StyleRange.NONE) + target.borderStyle= template.borderStyle; + if (template.borderColor != null) + target.borderColor= template.borderColor; + + } else { + target.font= template.font; + target.fontStyle= template.fontStyle; +// target.metrics= template.metrics; + target.foreground= template.foreground; + target.background= template.background; + target.strikeout= template.strikeout; + target.strikeoutColor= template.strikeoutColor; + target.underline= template.underline; + target.underlineStyle= template.underlineStyle; + target.underlineColor= template.underlineColor; + target.borderStyle= template.borderStyle; + target.borderColor= template.borderColor; + } + } + + /** + * Checks whether the given range is a subrange of the presentation's + * default style range. + * + * @param range the range to be checked + * @exception IllegalArgumentException if range is not a subrange of the presentation's default range + */ + private void checkConsistency(StyleRange range) { + + if (range == null) + throw new IllegalArgumentException(); + + if (fDefaultRange != null) { + + if (range.start < fDefaultRange.start) + range.start= fDefaultRange.start; + + int defaultEnd= fDefaultRange.start + fDefaultRange.length; + int end= range.start + range.length; + if (end > defaultEnd) + range.length -= (end - defaultEnd); + } + } + + /** + * Returns the index of the first range which overlaps with the + * specified window. + * + * @param window the window to be used for searching + * @return the index of the first range overlapping with the window + */ + private int getFirstIndexInWindow(IRegion window) { + if (window != null) { + int start= window.getOffset(); + int i= -1, j= fRanges.size(); + while (j - i > 1) { + int k= (i + j) >> 1; + StyleRange r= (StyleRange) fRanges.get(k); + if (r.start + r.length > start) + j= k; + else + i= k; + } + return j; + } + return 0; + } + + /** + * Returns the index of the first range which comes after the specified window and does + * not overlap with this window. + * + * @param window the window to be used for searching + * @return the index of the first range behind the window and not overlapping with the window + */ + private int getFirstIndexAfterWindow(IRegion window) { + if (window != null) { + int end= window.getOffset() + window.getLength(); + int i= -1, j= fRanges.size(); + while (j - i > 1) { + int k= (i + j) >> 1; + StyleRange r= (StyleRange) fRanges.get(k); + if (r.start < end) + i= k; + else + j= k; + } + return j; + } + return fRanges.size(); + } + + /** + * Returns a style range which is relative to the specified window and + * appropriately clipped if necessary. The original style range is not + * modified. + * + * @param window the reference window + * @param range the absolute range + * @return the window relative range based on the absolute range + */ + private StyleRange createWindowRelativeRange(IRegion window, StyleRange range) { + if (window == null || range == null) + return range; + + int start= range.start - window.getOffset(); + if (start < 0) + start= 0; + + int rangeEnd= range.start + range.length; + int windowEnd= window.getOffset() + window.getLength(); + int end= (rangeEnd > windowEnd ? windowEnd : rangeEnd); + end -= window.getOffset(); + + StyleRange newRange= (StyleRange) range.clone(); + newRange.start= start; + newRange.length= end - start; + return newRange; + } + + /** + * Returns the region which is relative to the specified window and + * appropriately clipped if necessary. + * + * @param coverage the absolute coverage + * @return the window relative region based on the absolute coverage + * @since 3.0 + */ + private IRegion createWindowRelativeRegion(IRegion coverage) { + if (fResultWindow == null || coverage == null) + return coverage; + + int start= coverage.getOffset() - fResultWindow.getOffset(); + if (start < 0) + start= 0; + + int rangeEnd= coverage.getOffset() + coverage.getLength(); + int windowEnd= fResultWindow.getOffset() + fResultWindow.getLength(); + int end= (rangeEnd > windowEnd ? windowEnd : rangeEnd); + end -= fResultWindow.getOffset(); + + return new Region(start, end - start); + } + + /** + * Returns an iterator which enumerates all style ranged which define a style + * different from the presentation's default style range. The default style range + * is not enumerated. + * + * @return a style range iterator + */ + public Iterator getNonDefaultStyleRangeIterator() { + return new FilterIterator(fDefaultRange != null); + } + + /** + * Returns an iterator which enumerates all style ranges of this presentation + * except the default style range. The returned <code>StyleRange</code>s + * are relative to the start of the presentation's result window. + * + * @return a style range iterator + */ + public Iterator getAllStyleRangeIterator() { + return new FilterIterator(false); + } + + /** + * Returns whether this collection contains any style range including + * the default style range. + * + * @return <code>true</code> if there is no style range in this presentation + */ + public boolean isEmpty() { + return (fDefaultRange == null && getDenumerableRanges() == 0); + } + + /** + * Returns the number of style ranges in the presentation not counting the default + * style range. + * + * @return the number of style ranges in the presentation excluding the default style range + */ + public int getDenumerableRanges() { + int size= getFirstIndexAfterWindow(fResultWindow) - getFirstIndexInWindow(fResultWindow); + return (size < 0 ? 0 : size); + } + + /** + * Returns the style range with the smallest offset ignoring the default style range or null + * if the presentation is empty. + * + * @return the style range with the smallest offset different from the default style range + */ + public StyleRange getFirstStyleRange() { + try { + + StyleRange range= (StyleRange) fRanges.get(getFirstIndexInWindow(fResultWindow)); + return createWindowRelativeRange(fResultWindow, range); + + } catch (NoSuchElementException x) { + } catch (IndexOutOfBoundsException x) { + } + + return null; + } + + /** + * Returns the style range with the highest offset ignoring the default style range. + * + * @return the style range with the highest offset different from the default style range + */ + public StyleRange getLastStyleRange() { + try { + + StyleRange range= (StyleRange) fRanges.get(getFirstIndexAfterWindow(fResultWindow) - 1); + return createWindowRelativeRange(fResultWindow, range); + + } catch (NoSuchElementException x) { + return null; + } catch (IndexOutOfBoundsException x) { + return null; + } + } + + /** + * Returns the coverage of this presentation as clipped by the presentation's + * result window. + * + * @return the coverage of this presentation + */ + public IRegion getCoverage() { + + if (fDefaultRange != null) { + StyleRange range= getDefaultStyleRange(); + return new Region(range.start, range.length); + } + + StyleRange first= getFirstStyleRange(); + StyleRange last= getLastStyleRange(); + + if (first == null || last == null) + return null; + + return new Region(first.start, last.start - first. start + last.length); + } + + /** + * Returns the extent of this presentation clipped by the + * presentation's result window. + * + * @return the clipped extent + * @since 3.0 + */ + public IRegion getExtent() { + if (fExtent != null) + return createWindowRelativeRegion(fExtent); + return getCoverage(); + } + + /** + * Clears this presentation by resetting all applied changes. + * @since 2.0 + */ + public void clear() { + fDefaultRange= null; + fResultWindow= null; + fRanges.clear(); + } + + +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextViewer.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextViewer.java new file mode 100644 index 000000000..a21005da0 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/TextViewer.java @@ -0,0 +1,621 @@ +/******************************************************************************* + * Copyright (c) 2000, 2014 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Tom Eicher (Avaloq Evolution AG) - block selection mode + * Markus Schorn <markus.schorn@windriver.com> - shift with trailing empty line - https://bugs.eclipse.org/325438 + *******************************************************************************/ +package org.eclipse.jface.text; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javafx.scene.layout.AnchorPane; + +import org.eclipse.fx.ui.controls.styledtext.StyleRange; +import org.eclipse.fx.ui.controls.styledtext.StyledTextArea; +import org.eclipse.jface.text.projection.ChildDocument; +import org.eclipse.jface.text.projection.ChildDocumentManager; +import org.eclipse.jface.viewers.Viewer; + +public class TextViewer extends Viewer implements + ITextViewer, ITextViewerExtension, ITextViewerExtension2, ITextViewerExtension4, ITextViewerExtension6, ITextViewerExtension7, ITextViewerExtension8 + /*, + IEditingSupportRegistry, ITextOperationTarget, ITextOperationTargetExtension, + IWidgetTokenOwner, IWidgetTokenOwnerExtension, IPostSelectionProvider*/ { + private StyledTextArea fTextWidget; + private IDocument fVisibleDocument; + private VisibleDocumentListener fVisibleDocumentListener= new VisibleDocumentListener(); + private ISlaveDocumentManager fSlaveDocumentManager; + private IDocumentInformationMapping fInformationMapping; + private IDocumentAdapter fDocumentAdapter; + private WidgetCommand fWidgetCommand= new WidgetCommand(); + protected List fTextListeners; + private int fRedrawCounter= 0; + private IRegion fLastSentSelectionChange; + private String fPartitioning; + private IDocument fDocument; + private boolean fReplaceTextPresentation; + private DocumentRewriteSessionListener fDocumentRewriteSessionListener= new DocumentRewriteSessionListener(); + private IRewriteTarget fRewriteTarget; + private ViewerState fViewerState; + private List fTextInputListeners; + protected Position fMarkPosition; + private final String MARK_POSITION_CATEGORY="__mark_category_" + hashCode(); //$NON-NLS-1$ + private final IPositionUpdater fMarkPositionUpdater= new DefaultPositionUpdater(MARK_POSITION_CATEGORY); + private List fTextPresentationListeners; + + public TextViewer() { + createControl(); + } + + protected void createControl() { + fTextWidget = createTextWidget(); + AnchorPane.setLeftAnchor(fTextWidget, 0.0); + AnchorPane.setRightAnchor(fTextWidget, 0.0); + AnchorPane.setTopAnchor(fTextWidget, 0.0); + AnchorPane.setBottomAnchor(fTextWidget, 0.0); + getChildren().add(fTextWidget); + } + + protected StyledTextArea getTextWidget() { + return fTextWidget; + } + + protected StyledTextArea createTextWidget() { + StyledTextArea styledText= new StyledTextArea(); +// styledText.setLeftMargin(Math.max(styledText.getLeftMargin(), 2)); + return styledText; + } + + public void setInput(Object input) { + + IDocument document= null; + if (input instanceof IDocument) + document= (IDocument) input; + + setDocument(document); + } + + public Object getInput() { + return getDocument(); + } + + public void setDocumentPartitioning(String partitioning) { + fPartitioning= partitioning; + } + + /** + * Sets this viewer's visible document. The visible document represents the + * visible region of the viewer's input document. + * + * @param document the visible document + */ + protected void setVisibleDocument(IDocument document) { + if (fVisibleDocument == document && fVisibleDocument instanceof ChildDocument) { + // optimization for new child documents + return; + } + + if (fVisibleDocument != null) { + if (fVisibleDocumentListener != null) + fVisibleDocument.removeDocumentListener(fVisibleDocumentListener); + if (fVisibleDocument != document) + freeSlaveDocument(fVisibleDocument); + } + + fVisibleDocument= document; + initializeDocumentInformationMapping(fVisibleDocument); + + initializeWidgetContents(); + +//TODO needs porting +// fFindReplaceDocumentAdapter= null; + if (fVisibleDocument != null && fVisibleDocumentListener != null) + fVisibleDocument.addDocumentListener(fVisibleDocumentListener); + } + + public IDocument getDocument() { + return fDocument; + } + + public void setDocument(IDocument document) { + fReplaceTextPresentation= true; + fireInputDocumentAboutToBeChanged(fDocument, document); + + IDocument oldDocument= fDocument; + fDocument= document; + + setVisibleDocument(fDocument); +//TODO needs porting +// resetPlugins(); + inputChanged(fDocument, oldDocument); + + fireInputDocumentChanged(oldDocument, fDocument); + fLastSentSelectionChange= null; + fReplaceTextPresentation= false; + } + + public IRegion getVisibleRegion() { + + IDocument document= getVisibleDocument(); + if (document instanceof ChildDocument) { + Position p= ((ChildDocument) document).getParentDocumentRange(); + return new Region(p.getOffset(), p.getLength()); + } + + return new Region(0, document == null ? 0 : document.getLength()); + } + + protected void fireInputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { + List listener= fTextInputListeners; + if (listener != null) { + for (int i= 0; i < listener.size(); i++) { + ITextInputListener l= (ITextInputListener) listener.get(i); + l.inputDocumentAboutToBeChanged(oldInput, newInput); + } + } + } + + protected void fireInputDocumentChanged(IDocument oldInput, IDocument newInput) { + List listener= fTextInputListeners; + if (listener != null) { + for (int i= 0; i < listener.size(); i++) { + ITextInputListener l= (ITextInputListener) listener.get(i); + l.inputDocumentChanged(oldInput, newInput); + } + } + } + + protected IDocument getVisibleDocument() { + return fVisibleDocument; + } + + protected void freeSlaveDocument(IDocument slave) { + ISlaveDocumentManager manager= getSlaveDocumentManager(); + if (manager != null && manager.isSlaveDocument(slave)) + manager.freeSlaveDocument(slave); + } + + protected ISlaveDocumentManager getSlaveDocumentManager() { + if (fSlaveDocumentManager == null) + fSlaveDocumentManager= createSlaveDocumentManager(); + return fSlaveDocumentManager; + } + + protected ISlaveDocumentManager createSlaveDocumentManager() { + return new ChildDocumentManager(); + } + + protected void initializeDocumentInformationMapping(IDocument visibleDocument) { + ISlaveDocumentManager manager= getSlaveDocumentManager(); + fInformationMapping= manager == null ? null : manager.createMasterSlaveMapping(visibleDocument); + } + + protected void inputChanged(Object newInput, Object oldInput) { + + IDocument oldDocument= (IDocument) oldInput; + if (oldDocument != null) { + + if (fMarkPosition != null && !fMarkPosition.isDeleted()) + oldDocument.removePosition(fMarkPosition); + + try { + oldDocument.removePositionUpdater(fMarkPositionUpdater); + oldDocument.removePositionCategory(MARK_POSITION_CATEGORY); + + } catch (BadPositionCategoryException e) { + } + } + + fMarkPosition= null; + + if (oldDocument instanceof IDocumentExtension4) { + IDocumentExtension4 document= (IDocumentExtension4) oldDocument; + document.removeDocumentRewriteSessionListener(fDocumentRewriteSessionListener); + } + +// super.inputChanged(newInput, oldInput); + + if (newInput instanceof IDocumentExtension4) { + IDocumentExtension4 document= (IDocumentExtension4) newInput; + document.addDocumentRewriteSessionListener(fDocumentRewriteSessionListener); + } + + IDocument newDocument= (IDocument) newInput; + if (newDocument != null) { + newDocument.addPositionCategory(MARK_POSITION_CATEGORY); + newDocument.addPositionUpdater(fMarkPositionUpdater); + } + } + + private void initializeWidgetContents() { + + if (fTextWidget != null && fVisibleDocument != null) { + + // set widget content + if (fDocumentAdapter == null) + fDocumentAdapter= createDocumentAdapter(); + + fDocumentAdapter.setDocument(fVisibleDocument); + fTextWidget.setContent(fDocumentAdapter); + System.err.println(fDocumentAdapter); + + // invalidate presentation + invalidateTextPresentation(); + } + } + + protected IDocumentAdapter createDocumentAdapter() { + return new DefaultDocumentAdapter(); + } + + public final void invalidateTextPresentation() { + if (fVisibleDocument != null) { + fWidgetCommand.event= null; + fWidgetCommand.start= 0; + fWidgetCommand.length= fVisibleDocument.getLength(); + fWidgetCommand.text= fVisibleDocument.get(); + updateTextListeners(fWidgetCommand); + } + } + + protected void updateTextListeners(WidgetCommand cmd) { + List textListeners= fTextListeners; + if (textListeners != null) { + textListeners= new ArrayList(textListeners); + DocumentEvent event= cmd.event; + if (event instanceof SlaveDocumentEvent) + event= ((SlaveDocumentEvent) event).getMasterEvent(); + + TextEvent e= new TextEvent(cmd.start, cmd.length, cmd.text, cmd.preservedText, event, redraws()); + for (int i= 0; i < textListeners.size(); i++) { + ITextListener l= (ITextListener) textListeners.get(i); + l.textChanged(e); + } + } + } + + protected final boolean redraws() { + return fRedrawCounter <= 0; + } + + protected void handleVisibleDocumentAboutToBeChanged(DocumentEvent event) { + } + + protected void handleVisibleDocumentChanged(DocumentEvent event) { + } + + public void addTextListener(ITextListener listener) { + + Assert.isNotNull(listener); + + if (fTextListeners == null) + fTextListeners= new ArrayList(); + + if (!fTextListeners.contains(listener)) + fTextListeners.add(listener); + } + + public void removeTextListener(ITextListener listener) { + Assert.isNotNull(listener); + + if (fTextListeners != null) { + fTextListeners.remove(listener); + if (fTextListeners.size() == 0) + fTextListeners= null; + } + } + + public void addTextInputListener(ITextInputListener listener) { + + Assert.isNotNull(listener); + + if (fTextInputListeners == null) + fTextInputListeners= new ArrayList(); + + if (!fTextInputListeners.contains(listener)) + fTextInputListeners.add(listener); + } + + public void removeTextInputListener(ITextInputListener listener) { + + Assert.isNotNull(listener); + + if (fTextInputListeners != null) { + fTextInputListeners.remove(listener); + if (fTextInputListeners.size() == 0) + fTextInputListeners= null; + } + } + + public void changeTextPresentation(TextPresentation presentation, boolean controlRedraw) { + + if (presentation == null || !redraws()) + return; + + if (fTextWidget == null) + return; + + + /* + * Call registered text presentation listeners + * and let them apply their presentation. + */ + if (fTextPresentationListeners != null) { + ArrayList listeners= new ArrayList(fTextPresentationListeners); + for (int i= 0, size= listeners.size(); i < size; i++) { + ITextPresentationListener listener= (ITextPresentationListener)listeners.get(i); + listener.applyTextPresentation(presentation); + } + } + + if (presentation.isEmpty()) + return; + + if (controlRedraw) + fTextWidget.setRedraw(false); + + if (fReplaceTextPresentation) + applyTextPresentation(presentation); + else + addPresentation(presentation); + + if (controlRedraw) + fTextWidget.setRedraw(true); + } + + private void addPresentation(TextPresentation presentation) { + + StyleRange range= presentation.getDefaultStyleRange(); + if (range != null) { + + range= modelStyleRange2WidgetStyleRange(range); + if (range != null) + fTextWidget.setStyleRange(range); + + ArrayList ranges= new ArrayList(presentation.getDenumerableRanges()); + Iterator e= presentation.getNonDefaultStyleRangeIterator(); + while (e.hasNext()) { + range= (StyleRange) e.next(); + range= modelStyleRange2WidgetStyleRange(range); + if (range != null) + ranges.add(range); + } + + if (!ranges.isEmpty()) + fTextWidget.replaceStyleRanges(0, 0, (StyleRange[])ranges.toArray(new StyleRange[ranges.size()])); + + } else { + IRegion region= modelRange2WidgetRange(presentation.getCoverage()); + if (region == null) + return; + + List list= new ArrayList(presentation.getDenumerableRanges()); + Iterator e= presentation.getAllStyleRangeIterator(); + while (e.hasNext()) { + range= (StyleRange) e.next(); + range= modelStyleRange2WidgetStyleRange(range); + if (range != null) + list.add(range); + } + + if (!list.isEmpty()) { + StyleRange[] ranges= new StyleRange[list.size()]; + list.toArray(ranges); + fTextWidget.replaceStyleRanges(region.getOffset(), region.getLength(), ranges); + } + } + } + + private void applyTextPresentation(TextPresentation presentation) { + List list= new ArrayList(presentation.getDenumerableRanges()); + Iterator e= presentation.getAllStyleRangeIterator(); + while (e.hasNext()) { + StyleRange range= (StyleRange) e.next(); + range= modelStyleRange2WidgetStyleRange(range); + if (range != null) + list.add(range); + } + + if (!list.isEmpty()) { + StyleRange[] ranges= new StyleRange[list.size()]; + list.toArray(ranges); + fTextWidget.setStyleRanges(ranges); + } + } + + protected StyleRange modelStyleRange2WidgetStyleRange(StyleRange range) { + IRegion region= modelRange2WidgetRange(new Region(range.start, range.length)); + if (region != null) { + StyleRange result= (StyleRange) range.clone(); + result.start= region.getOffset(); + result.length= region.getLength(); + return result; + } + return null; + } + + public IRegion modelRange2WidgetRange(IRegion modelRange) { + if (fInformationMapping == null) + return modelRange; + + try { + + if (modelRange.getLength() < 0) { + Region reversed= new Region(modelRange.getOffset() + modelRange.getLength(), -modelRange.getLength()); + IRegion result= fInformationMapping.toImageRegion(reversed); + if (result != null) + return new Region(result.getOffset() + result.getLength(), -result.getLength()); + } + return fInformationMapping.toImageRegion(modelRange); + + } catch (BadLocationException x) { + } + + return null; + } + + public IRewriteTarget getRewriteTarget() { + if (fRewriteTarget == null) + fRewriteTarget= new RewriteTarget(); + return fRewriteTarget; + } + + public final void setRedraw(boolean redraw) { +//TODO needs porting +// setRedraw(redraw, -1); + } + + class VisibleDocumentListener implements IDocumentListener { + + public void documentAboutToBeChanged(DocumentEvent e) { + if (e.getDocument() == getVisibleDocument()) + fWidgetCommand.setEvent(e); + handleVisibleDocumentAboutToBeChanged(e); + } + + public void documentChanged(DocumentEvent e) { + if (fWidgetCommand.event == e) + updateTextListeners(fWidgetCommand); + fLastSentSelectionChange= null; + handleVisibleDocumentChanged(e); + } + } + + /** + * Represents a replace command that brings the text viewer's text widget + * back in synchronization with text viewer's document after the document + * has been changed. + */ + protected class WidgetCommand { + + /** The document event encapsulated by this command. */ + public DocumentEvent event; + /** The start of the event. */ + public int start; + /** The length of the event. */ + public int length; + /** The inserted and replaced text segments of <code>event</code>. */ + public String text; + /** The replaced text segments of <code>event</code>. */ + public String preservedText; + + /** + * Translates a document event into the presentation coordinates of this text viewer. + * + * @param e the event to be translated + */ + public void setEvent(DocumentEvent e) { + + event= e; + + start= e.getOffset(); + length= e.getLength(); + text= e.getText(); + + if (length != 0) { + try { + + if (e instanceof SlaveDocumentEvent) { + SlaveDocumentEvent slave= (SlaveDocumentEvent) e; + DocumentEvent master= slave.getMasterEvent(); + if (master != null) + preservedText= master.getDocument().get(master.getOffset(), master.getLength()); + } else { + preservedText= e.getDocument().get(e.getOffset(), e.getLength()); + } + + } catch (BadLocationException x) { + preservedText= null; +// if (TRACE_ERRORS) +// System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.WidgetCommand.setEvent")); //$NON-NLS-1$ + } + } else + preservedText= null; + } + } + + private class DocumentRewriteSessionListener implements IDocumentRewriteSessionListener { + + /* + * @see org.eclipse.jface.text.IDocumentRewriteSessionListener#documentRewriteSessionChanged(org.eclipse.jface.text.DocumentRewriteSessionEvent) + */ + public void documentRewriteSessionChanged(DocumentRewriteSessionEvent event) { + IRewriteTarget target= TextViewer.this.getRewriteTarget(); + final boolean toggleRedraw; +// if (REDRAW_BUG_158746) +// toggleRedraw= true; +// else + toggleRedraw= event.getSession().getSessionType() != DocumentRewriteSessionType.UNRESTRICTED_SMALL; + final boolean viewportStabilize= !toggleRedraw; + if (DocumentRewriteSessionEvent.SESSION_START == event.getChangeType()) { + if (toggleRedraw) + target.setRedraw(false); + target.beginCompoundChange(); + if (viewportStabilize && fViewerState == null) + fViewerState= new ViewerState(); + } else if (DocumentRewriteSessionEvent.SESSION_STOP == event.getChangeType()) { + if (viewportStabilize && fViewerState != null) { + fViewerState.restore(true); + fViewerState= null; + } + target.endCompoundChange(); + if (toggleRedraw) + target.setRedraw(true); + } + } + } + + /** + * The viewer's rewrite target. + * @since 2.0 + */ + class RewriteTarget implements IRewriteTarget { + + /* + * @see org.eclipse.jface.text.IRewriteTarget#beginCompoundChange() + */ + public void beginCompoundChange() { +//TODO needs porting +// if (fUndoManager != null) +// fUndoManager.beginCompoundChange(); + } + + /* + * @see org.eclipse.jface.text.IRewriteTarget#endCompoundChange() + */ + public void endCompoundChange() { +//TODO needs porting +// if (fUndoManager != null) +// fUndoManager.endCompoundChange(); + } + + /* + * @see org.eclipse.jface.text.IRewriteTarget#getDocument() + */ + public IDocument getDocument() { + return TextViewer.this.getDocument(); + } + + /* + * @see org.eclipse.jface.text.IRewriteTarget#setRedraw(boolean) + */ + public void setRedraw(boolean redraw) { + TextViewer.this.setRedraw(redraw); + } + } + + private final class ViewerState { +//TODO needs porting + public void restore(boolean restoreViewport) { + + } + } +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationDamager.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationDamager.java new file mode 100644 index 000000000..4039cb96a --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationDamager.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text.presentation; + + + +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITypedRegion; + + +/** + * A presentation damager is a strategy used by a presentation reconciler to + * determine the region of the document's presentation which must be rebuilt + * because of a document change. A presentation damager is assumed to be + * specific for a particular document content type. A presentation damager is + * expected to return a damage region which is a valid input for a presentation + * repairer. I.e. having access to the damage region only the repairer must be + * able to derive all the information needed to successfully repair this region. + * <p> + * This interface must either be implemented by clients or clients use the + * rule-based default implementation + * {@link org.eclipse.jface.text.rules.DefaultDamagerRepairer}. Implementers + * should be registered with a presentation reconciler in order get involved in + * the reconciling process.</p> + * + * @see IPresentationReconciler + * @see IDocument + * @see DocumentEvent + * @see IPresentationRepairer + */ +public interface IPresentationDamager { + + /** + * Tells the presentation damager on which document it will work. + * + * @param document the damager's working document + */ + void setDocument(IDocument document); + + /** + * Returns the damage in the document's presentation caused by the given document change. + * The damage is restricted to the specified partition for which the presentation damager is + * responsible. The damage may also depend on whether the document change also caused changes + * of the document's partitioning. + * + * @param partition the partition inside which the damage must be determined + * @param event the event describing the change whose damage must be determined + * @param documentPartitioningChanged indicates whether the given change changed the document's partitioning + * @return the computed damage + */ + IRegion getDamageRegion(ITypedRegion partition, DocumentEvent event, boolean documentPartitioningChanged); +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationReconciler.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationReconciler.java new file mode 100644 index 000000000..edfdc4f2c --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationReconciler.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text.presentation; + + +import org.eclipse.jface.text.ITextViewer; + + +/** + * An <code>IPresentationReconciler</code> defines and maintains the + * representation of a text viewer's document in the presence of changes applied + * to the document. An <code>IPresentationReconciler</code> is a + * <code>ITextViewer</code> add-on. + * <p> + * The presentation reconciler keeps track of changes applied to the text + * viewer. It sends each change to presentation damagers which are registered + * for the content types of the regions in which the change occurred. The + * presentation reconciler passes the computed damage to presentation repairer + * which construct text presentations. When applied to the presentation + * reconciler's text viewer, those text presentations bring the document's + * presentation in sync with the document's content and thus repair the damage. + * A presentation damager is expected to return damage which is a valid input + * for a presentation repairer registered for the same content type as the + * damager. + * </p> + * <p> + * A presentation reconciler should always be configured with a pair of + * damager/repairer strategies. I.e. for each damager there should be a + * corresponding repairer. + * </p> + * <p> + * The interface may be implemented by clients. Clients may use + * <code>PresentationReconciler</code> as the standard implementation of this + * interface. + * </p> + * <p> + * In order to provided backward compatibility for clients of + * <code>IPresentationReconciler</code>, extension interfaces are used to + * provide a means of evolution. The following extension interface exists: + * <ul> + * <li> + * {@link org.eclipse.jface.text.presentation.IPresentationReconcilerExtension} + * since version 3.0 adding support for documents with multiple partitionings. + * </li> + * </ul> + * </p> + * + * @see org.eclipse.jface.text.presentation.IPresentationReconcilerExtension + * @see org.eclipse.jface.text.ITextViewer + * @see org.eclipse.jface.text.presentation.IPresentationDamager + * @see org.eclipse.jface.text.presentation.IPresentationRepairer + * @see org.eclipse.jface.text.TextPresentation + */ +public interface IPresentationReconciler { + + /** + * Installs this presentation reconciler on the given text viewer. After + * this method has been finished, the reconciler is operational. I.e., it + * works without requesting further client actions until + * <code>uninstall</code> is called. + * <p> + * The <code>install</code> and <code>uninstall</code> methods must be + * called in sequence; i.e. repeatedly calling <code>install</code> + * without calling <code>uninstall</code> may throw an exception. + * </p> + * + * @param viewer the viewer on which this presentation reconciler is + * installed + */ + void install(ITextViewer viewer); + + /** + * Removes the reconciler from the text viewer it has previously been + * installed on. + */ + void uninstall(); + + /** + * Returns the presentation damager registered with this presentation reconciler + * for the specified content type. + * + * @param contentType the content type for which to determine the damager + * @return the presentation damager registered for the given content type, or + * <code>null</code> if there is no damager + */ + IPresentationDamager getDamager(String contentType); + + /** + * Returns the presentation repairer registered with this presentation reconciler + * for the specified content type. + * + * @param contentType the content type for which to determine the repairer + * @return the presentation repairer registered for the given content type, or + * <code>null</code> if there is no repairer + */ + IPresentationRepairer getRepairer(String contentType); +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationReconcilerExtension.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationReconcilerExtension.java new file mode 100644 index 000000000..1fc459fd2 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationReconcilerExtension.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text.presentation; + +/** + * Extension interface for {@link IPresentationReconciler}. Adds awareness of + * documents with multiple partitions. + * + * @since 3.0 + */ +public interface IPresentationReconcilerExtension { + + /** + * Returns the document partitioning this presentation reconciler is using. + * + * @return the document partitioning this presentation reconciler is using + */ + String getDocumentPartitioning(); +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationRepairer.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationRepairer.java new file mode 100644 index 000000000..a07f8e681 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/IPresentationRepairer.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text.presentation; + + + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jface.text.TextPresentation; + + +/** + * A presentation repairer is a strategy used by a presentation reconciler to + * rebuild a damaged region in a document's presentation. A presentation + * repairer is assumed to be specific for a particular document content type. + * The presentation repairer gets the region which it should repair and + * constructs a "repair description". The presentation repairer merges the steps + * contained within this description into the text presentation passed into + * <code>createPresentation</code>. + * <p> + * This interface may be implemented by clients. Alternatively, clients may use + * the rule-based default implementation + * {@link org.eclipse.jface.text.rules.DefaultDamagerRepairer}. Implementers + * should be registered with a presentation reconciler in order get involved in + * the reconciling process. + * </p> + * + * @see IPresentationReconciler + * @see IDocument + * @see org.eclipse.swt.custom.StyleRange + * @see TextPresentation + */ +public interface IPresentationRepairer { + + + /** + * Tells the presentation repairer on which document it will work. + * + * @param document the damager's working document + */ + void setDocument(IDocument document); + + /** + * Fills the given presentation with the style ranges which when applied to the + * presentation reconciler's text viewer repair the presentation damage described by + * the given region. + * + * @param presentation the text presentation to be filled by this repairer + * @param damage the damage to be repaired + */ + void createPresentation(TextPresentation presentation, ITypedRegion damage); +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/PresentationReconciler.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/PresentationReconciler.java new file mode 100644 index 000000000..bae2990a6 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/presentation/PresentationReconciler.java @@ -0,0 +1,595 @@ +/******************************************************************************* + * Copyright (c) 2000, 2012 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.jface.text.presentation; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.fx.ui.controls.styledtext.StyleRange; +import org.eclipse.jface.text.Assert; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.BadPositionCategoryException; +import org.eclipse.jface.text.DefaultPositionUpdater; +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.DocumentPartitioningChangedEvent; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentExtension3; +import org.eclipse.jface.text.IDocumentListener; +import org.eclipse.jface.text.IDocumentPartitioningListener; +import org.eclipse.jface.text.IDocumentPartitioningListenerExtension; +import org.eclipse.jface.text.IDocumentPartitioningListenerExtension2; +import org.eclipse.jface.text.IPositionUpdater; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextInputListener; +import org.eclipse.jface.text.ITextListener; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.ITextViewerExtension5; +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextEvent; +import org.eclipse.jface.text.TextPresentation; +import org.eclipse.jface.text.TextUtilities; +import org.eclipse.jface.text.TypedPosition; + + + +/** + * Standard implementation of <code>IPresentationReconciler</code>. This + * implementation assumes that the tasks performed by its presentation damagers + * and repairers are lightweight and of low cost. This presentation reconciler + * runs in the UI thread and always repairs the complete damage caused by a + * document change rather than just the portion overlapping with the viewer's + * viewport. + * <p> + * Usually, clients instantiate this class and configure it before using it. + * </p> + */ +public class PresentationReconciler implements IPresentationReconciler, IPresentationReconcilerExtension { + + /** Prefix of the name of the position category for tracking damage regions. */ + protected final static String TRACKED_PARTITION= "__reconciler_tracked_partition"; //$NON-NLS-1$ + + + /** + * Internal listener class. + */ + class InternalListener implements + ITextInputListener, IDocumentListener, ITextListener, + IDocumentPartitioningListener, IDocumentPartitioningListenerExtension, IDocumentPartitioningListenerExtension2 { + + /** Set to <code>true</code> if between a document about to be changed and a changed event. */ + private boolean fDocumentChanging= false; + /** + * The cached redraw state of the text viewer. + * @since 3.0 + */ + private boolean fCachedRedrawState= true; + + /* + * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument, IDocument) + */ + public void inputDocumentAboutToBeChanged(IDocument oldDocument, IDocument newDocument) { + if (oldDocument != null) { + try { + + fViewer.removeTextListener(this); + oldDocument.removeDocumentListener(this); + oldDocument.removeDocumentPartitioningListener(this); + + oldDocument.removePositionUpdater(fPositionUpdater); + oldDocument.removePositionCategory(fPositionCategory); + + } catch (BadPositionCategoryException x) { + // should not happened for former input documents; + } + } + } + + /* + * @see ITextInputListener#inputDocumenChanged(IDocument, IDocument) + */ + public void inputDocumentChanged(IDocument oldDocument, IDocument newDocument) { + + fDocumentChanging= false; + fCachedRedrawState= true; + + if (newDocument != null) { + + newDocument.addPositionCategory(fPositionCategory); + newDocument.addPositionUpdater(fPositionUpdater); + + newDocument.addDocumentPartitioningListener(this); + newDocument.addDocumentListener(this); + fViewer.addTextListener(this); + + setDocumentToDamagers(newDocument); + setDocumentToRepairers(newDocument); + processDamage(new Region(0, newDocument.getLength()), newDocument); + } + } + + /* + * @see IDocumentPartitioningListener#documentPartitioningChanged(IDocument) + */ + public void documentPartitioningChanged(IDocument document) { + if (!fDocumentChanging && fCachedRedrawState) + processDamage(new Region(0, document.getLength()), document); + else + fDocumentPartitioningChanged= true; + } + + /* + * @see IDocumentPartitioningListenerExtension#documentPartitioningChanged(IDocument, IRegion) + * @since 2.0 + */ + public void documentPartitioningChanged(IDocument document, IRegion changedRegion) { + if (!fDocumentChanging && fCachedRedrawState) { + processDamage(new Region(changedRegion.getOffset(), changedRegion.getLength()), document); + } else { + fDocumentPartitioningChanged= true; + fChangedDocumentPartitions= changedRegion; + } + } + + /* + * @see org.eclipse.jface.text.IDocumentPartitioningListenerExtension2#documentPartitioningChanged(org.eclipse.jface.text.DocumentPartitioningChangedEvent) + * @since 3.0 + */ + public void documentPartitioningChanged(DocumentPartitioningChangedEvent event) { + IRegion changedRegion= event.getChangedRegion(getDocumentPartitioning()); + if (changedRegion != null) + documentPartitioningChanged(event.getDocument(), changedRegion); + } + + /* + * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent) + */ + public void documentAboutToBeChanged(DocumentEvent e) { + + fDocumentChanging= true; + if (fCachedRedrawState) { + try { + int offset= e.getOffset() + e.getLength(); + ITypedRegion region= getPartition(e.getDocument(), offset); + fRememberedPosition= new TypedPosition(region); + e.getDocument().addPosition(fPositionCategory, fRememberedPosition); + } catch (BadLocationException x) { + // can not happen + } catch (BadPositionCategoryException x) { + // should not happen on input elements + } + } + } + + /* + * @see IDocumentListener#documentChanged(DocumentEvent) + */ + public void documentChanged(DocumentEvent e) { + if (fCachedRedrawState) { + try { + e.getDocument().removePosition(fPositionCategory, fRememberedPosition); + } catch (BadPositionCategoryException x) { + // can not happen on input documents + } + } + fDocumentChanging= false; + } + + /* + * @see ITextListener#textChanged(TextEvent) + */ + public void textChanged(TextEvent e) { + + fCachedRedrawState= e.getViewerRedrawState(); + if (!fCachedRedrawState) + return; + + IRegion damage= null; + IDocument document= null; + + if (e.getDocumentEvent() == null) { + document= fViewer.getDocument(); + if (document != null) { + if (e.getOffset() == 0 && e.getLength() == 0 && e.getText() == null) { + // redraw state change, damage the whole document + damage= new Region(0, document.getLength()); + } else { + IRegion region= widgetRegion2ModelRegion(e); + if (region != null) { + try { + String text= document.get(region.getOffset(), region.getLength()); + DocumentEvent de= new DocumentEvent(document, region.getOffset(), region.getLength(), text); + damage= getDamage(de, false); + } catch (BadLocationException x) { + } + } + } + } + } else { + DocumentEvent de= e.getDocumentEvent(); + document= de.getDocument(); + damage= getDamage(de, true); + } + + if (damage != null && document != null) + processDamage(damage, document); + + fDocumentPartitioningChanged= false; + fChangedDocumentPartitions= null; + } + + /** + * Translates the given text event into the corresponding range of the viewer's document. + * + * @param e the text event + * @return the widget region corresponding the region of the given event or + * <code>null</code> if none + * @since 2.1 + */ + protected IRegion widgetRegion2ModelRegion(TextEvent e) { + + String text= e.getText(); + int length= text == null ? 0 : text.length(); + + if (fViewer instanceof ITextViewerExtension5) { + ITextViewerExtension5 extension= (ITextViewerExtension5) fViewer; + return extension.widgetRange2ModelRange(new Region(e.getOffset(), length)); + } + + IRegion visible= fViewer.getVisibleRegion(); + IRegion region= new Region(e.getOffset() + visible.getOffset(), length); + return region; + } + } + + /** The map of presentation damagers. */ + private Map fDamagers; + /** The map of presentation repairers. */ + private Map fRepairers; + /** The target viewer. */ + private ITextViewer fViewer; + /** The internal listener. */ + private InternalListener fInternalListener= new InternalListener(); + /** The name of the position category to track damage regions. */ + private String fPositionCategory; + /** The position updated for the damage regions' position category. */ + private IPositionUpdater fPositionUpdater; + /** The positions representing the damage regions. */ + private TypedPosition fRememberedPosition; + /** Flag indicating the receipt of a partitioning changed notification. */ + private boolean fDocumentPartitioningChanged= false; + /** The range covering the changed partitioning. */ + private IRegion fChangedDocumentPartitions= null; + /** + * The partitioning used by this presentation reconciler. + * @since 3.0 + */ + private String fPartitioning; + + /** + * Creates a new presentation reconciler. There are no damagers or repairers + * registered with this reconciler by default. The default partitioning + * <code>IDocumentExtension3.DEFAULT_PARTITIONING</code> is used. + */ + public PresentationReconciler() { + super(); + fPartitioning= IDocumentExtension3.DEFAULT_PARTITIONING; + fPositionCategory= TRACKED_PARTITION + hashCode(); + fPositionUpdater= new DefaultPositionUpdater(fPositionCategory); + } + + /** + * Sets the document partitioning for this presentation reconciler. + * + * @param partitioning the document partitioning for this presentation reconciler. + * @since 3.0 + */ + public void setDocumentPartitioning(String partitioning) { + Assert.isNotNull(partitioning); + fPartitioning= partitioning; + } + + /* + * @see org.eclipse.jface.text.presentation.IPresentationReconcilerExtension#geDocumenttPartitioning() + * @since 3.0 + */ + public String getDocumentPartitioning() { + return fPartitioning; + } + + /** + * Registers the given presentation damager for a particular content type. + * If there is already a damager registered for this type, the old damager + * is removed first. + * + * @param damager the presentation damager to register, or <code>null</code> to remove an existing one + * @param contentType the content type under which to register + */ + public void setDamager(IPresentationDamager damager, String contentType) { + + Assert.isNotNull(contentType); + + if (fDamagers == null) + fDamagers= new HashMap(); + + if (damager == null) + fDamagers.remove(contentType); + else + fDamagers.put(contentType, damager); + } + + /** + * Registers the given presentation repairer for a particular content type. + * If there is already a repairer registered for this type, the old repairer + * is removed first. + * + * @param repairer the presentation repairer to register, or <code>null</code> to remove an existing one + * @param contentType the content type under which to register + */ + public void setRepairer(IPresentationRepairer repairer, String contentType) { + + Assert.isNotNull(contentType); + + if (fRepairers == null) + fRepairers= new HashMap(); + + if (repairer == null) + fRepairers.remove(contentType); + else + fRepairers.put(contentType, repairer); + } + + /* + * @see IPresentationReconciler#install(ITextViewer) + */ + public void install(ITextViewer viewer) { + Assert.isNotNull(viewer); + + fViewer= viewer; + fViewer.addTextInputListener(fInternalListener); + + IDocument document= viewer.getDocument(); + if (document != null) + fInternalListener.inputDocumentChanged(null, document); + } + + /* + * @see IPresentationReconciler#uninstall() + */ + public void uninstall() { + fViewer.removeTextInputListener(fInternalListener); + + // Ensure we uninstall all listeners + fInternalListener.inputDocumentAboutToBeChanged(fViewer.getDocument(), null); + } + + /* + * @see IPresentationReconciler#getDamager(String) + */ + public IPresentationDamager getDamager(String contentType) { + + if (fDamagers == null) + return null; + + return (IPresentationDamager) fDamagers.get(contentType); + } + + /* + * @see IPresentationReconciler#getRepairer(String) + */ + public IPresentationRepairer getRepairer(String contentType) { + + if (fRepairers == null) + return null; + + return (IPresentationRepairer) fRepairers.get(contentType); + } + + /** + * Informs all registered damagers about the document on which they will work. + * + * @param document the document on which to work + */ + protected void setDocumentToDamagers(IDocument document) { + if (fDamagers != null) { + Iterator e= fDamagers.values().iterator(); + while (e.hasNext()) { + IPresentationDamager damager= (IPresentationDamager) e.next(); + damager.setDocument(document); + } + } + } + + /** + * Informs all registered repairers about the document on which they will work. + * + * @param document the document on which to work + */ + protected void setDocumentToRepairers(IDocument document) { + if (fRepairers != null) { + Iterator e= fRepairers.values().iterator(); + while (e.hasNext()) { + IPresentationRepairer repairer= (IPresentationRepairer) e.next(); + repairer.setDocument(document); + } + } + } + + /** + * Constructs a "repair description" for the given damage and returns this + * description as a text presentation. For this, it queries the partitioning + * of the damage region and asks the appropriate presentation repairer for + * each partition to construct the "repair description" for this partition. + * + * @param damage the damage to be repaired + * @param document the document whose presentation must be repaired + * @return the presentation repair description as text presentation or + * <code>null</code> if the partitioning could not be computed + */ + protected TextPresentation createPresentation(IRegion damage, IDocument document) { + try { + if (fRepairers == null || fRepairers.isEmpty()) { + TextPresentation presentation= new TextPresentation(damage, 100); + presentation.setDefaultStyleRange(new StyleRange(damage.getOffset(), damage.getLength(), null, null)); + return presentation; + } + + TextPresentation presentation= new TextPresentation(damage, 1000); + + ITypedRegion[] partitioning= TextUtilities.computePartitioning(document, getDocumentPartitioning(), damage.getOffset(), damage.getLength(), false); + for (int i= 0; i < partitioning.length; i++) { + ITypedRegion r= partitioning[i]; + IPresentationRepairer repairer= getRepairer(r.getType()); + if (repairer != null) + repairer.createPresentation(presentation, r); + } + + return presentation; + + } catch (BadLocationException x) { + return null; + } + } + + + /** + * Checks for the first and the last affected partition affected by a + * document event and calls their damagers. Invalidates everything from the + * start of the damage for the first partition until the end of the damage + * for the last partition. + * + * @param e the event describing the document change + * @param optimize <code>true</code> if partition changes should be + * considered for optimization + * @return the damaged caused by the change or <code>null</code> if + * computing the partitioning failed + * @since 3.0 + */ + private IRegion getDamage(DocumentEvent e, boolean optimize) { + int length= e.getText() == null ? 0 : e.getText().length(); + + if (fDamagers == null || fDamagers.isEmpty()) { + length= Math.max(e.getLength(), length); + length= Math.min(e.getDocument().getLength() - e.getOffset(), length); + return new Region(e.getOffset(), length); + } + + boolean isDeletion= length == 0; + IRegion damage= null; + try { + int offset= e.getOffset(); + if (isDeletion) + offset= Math.max(0, offset - 1); + ITypedRegion partition= getPartition(e.getDocument(), offset); + IPresentationDamager damager= getDamager(partition.getType()); + if (damager == null) + return null; + + IRegion r= damager.getDamageRegion(partition, e, fDocumentPartitioningChanged); + + if (!fDocumentPartitioningChanged && optimize && !isDeletion) { + damage= r; + } else { + + int damageStart= r.getOffset(); + int damageEnd= getDamageEndOffset(e); + + if (fChangedDocumentPartitions != null) { + damageStart= Math.min(damageStart, fChangedDocumentPartitions.getOffset()); + damageEnd= Math.max(damageEnd, fChangedDocumentPartitions.getOffset() + fChangedDocumentPartitions.getLength()); + } + + damage= damageEnd == -1 ? r : new Region(damageStart, damageEnd - damageStart); + } + + } catch (BadLocationException x) { + } + + return damage; + } + + /** + * Returns the end offset of the damage. If a partition has been split by + * the given document event also the second half of the original + * partition must be considered. This is achieved by using the remembered + * partition range. + * + * @param e the event describing the change + * @return the damage end offset (excluding) + * @exception BadLocationException if method accesses invalid offset + */ + private int getDamageEndOffset(DocumentEvent e) throws BadLocationException { + + IDocument d= e.getDocument(); + + int length= 0; + if (e.getText() != null) { + length= e.getText().length(); + if (length > 0) + -- length; + } + + ITypedRegion partition= getPartition(d, e.getOffset() + length); + int endOffset= partition.getOffset() + partition.getLength(); + if (endOffset == e.getOffset()) + return -1; + + int end= fRememberedPosition == null ? -1 : fRememberedPosition.getOffset() + fRememberedPosition.getLength(); + if (endOffset < end && end < d.getLength()) + partition= getPartition(d, end); + + IPresentationDamager damager= getDamager(partition.getType()); + if (damager == null) + return -1; + + IRegion r= damager.getDamageRegion(partition, e, fDocumentPartitioningChanged); + + return r.getOffset() + r.getLength(); + } + + /** + * Processes the given damage. + * @param damage the damage to be repaired + * @param document the document whose presentation must be repaired + */ + private void processDamage(IRegion damage, IDocument document) { + if (damage != null && damage.getLength() > 0) { + TextPresentation p= createPresentation(damage, document); + if (p != null) + applyTextRegionCollection(p); + } + } + + /** + * Applies the given text presentation to the text viewer the presentation + * reconciler is installed on. + * + * @param presentation the text presentation to be applied to the text viewer + */ + private void applyTextRegionCollection(TextPresentation presentation) { + fViewer.changeTextPresentation(presentation, false); + } + + /** + * Returns the partition for the given offset in the given document. + * + * @param document the document + * @param offset the offset + * @return the partition + * @throws BadLocationException if offset is invalid in the given document + * @since 3.0 + */ + private ITypedRegion getPartition(IDocument document, int offset) throws BadLocationException { + return TextUtilities.getPartition(document, getDocumentPartitioning(), offset, false); + } +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/DirtyRegion.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/DirtyRegion.java new file mode 100644 index 000000000..83b07ac53 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/DirtyRegion.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text.reconciler; + +import org.eclipse.jface.text.ITypedRegion; + + +/** + * A dirty region describes a document range which has been changed. + */ +public class DirtyRegion implements ITypedRegion { + + /** + * Identifies an insert operation. + */ + final static public String INSERT= "__insert"; //$NON-NLS-1$ + /** + * Identifies a remove operation. + */ + final static public String REMOVE= "__remove"; //$NON-NLS-1$ + + /** The region's offset. */ + private int fOffset; + /** The region's length. */ + private int fLength; + /** Indicates the type of the applied change. */ + private String fType; + /** The text which has been inserted. */ + private String fText; + + /** + * Creates a new dirty region. + * + * @param offset the offset within the document where the change occurred + * @param length the length of the text within the document that changed + * @param type the type of change that this region represents: {@link #INSERT} {@link #REMOVE} + * @param text the substitution text + */ + public DirtyRegion(int offset, int length, String type, String text) { + fOffset= offset; + fLength= length; + fType= normalizeTypeValue(type); + fText= text; + } + + /** + * Computes the normalized type value to ensure that the implementation can use object identity rather + * than equality. + * + * @param type the type value + * @return the normalized type value or <code>null</code> + * @since 3.1 + */ + private String normalizeTypeValue(String type) { + if (INSERT.equals(type)) + return INSERT; + if (REMOVE.equals(type)) + return REMOVE; + return null; + } + + /* + * @see ITypedRegion#getOffset() + */ + public int getOffset() { + return fOffset; + } + + /* + * @see ITypedRegion#getLength() + */ + public int getLength() { + return fLength; + } + + /* + * @see ITypedRegion#getType + */ + public String getType() { + return fType; + } + + /** + * Returns the text that changed as part of the region change. + * + * @return the changed text + */ + public String getText() { + return fText; + } + + /** + * Modify the receiver so that it encompasses the region specified by the dirty region. + * + * @param dr the dirty region with which to merge + */ + void mergeWith(DirtyRegion dr) { + int start= Math.min(fOffset, dr.fOffset); + int end= Math.max(fOffset + fLength, dr.fOffset + dr.fLength); + fOffset= start; + fLength= end - start; + fText= (dr.fText == null ? fText : (fText == null) ? dr.fText : fText + dr.fText); + } +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/IReconciler.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/IReconciler.java new file mode 100644 index 000000000..53a10d46a --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/IReconciler.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2000, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text.reconciler; + +import org.eclipse.jface.text.ITextViewer; + + +/** + * An <code>IReconciler</code> defines and maintains a model of the content + * of the text viewer's document in the presence of changes applied to this + * document. An <code>IReconciler</code> is a {@link org.eclipse.jface.text.ITextViewer} add-on. + * <p> + * Reconcilers are assumed to be asynchronous, i.e. they allow a certain + * temporal window of inconsistency between the document and the model of + * the content of this document. + * </p> + * <p> + * Reconcilers have a list of {@link org.eclipse.jface.text.reconciler.IReconcilingStrategy} + * objects each of which is registered for a particular document content type. + * The reconciler uses the strategy objects to react on the changes applied + * to the text viewer's document. + *</p> + * <p> + * In order to provide backward compatibility for clients of <code>IReconciler</code>, extension + * interfaces are used to provide a means of evolution. The following extension interfaces exist: + * <ul> + * <li>{@link org.eclipse.jface.text.reconciler.IReconcilerExtension} since version 3.0 introducing + * the ability to be aware of documents with multiple partitionings.</li> + * </ul> + * </p> + * <p> + * The interface can be implemented by clients. By default, clients use + * {@link org.eclipse.jface.text.reconciler.MonoReconciler} or + * {@link org.eclipse.jface.text.reconciler.Reconciler} as the standard + * implementers of this interface. + * </p> + * + * @see ITextViewer + * @see IReconcilingStrategy + */ +public interface IReconciler { + + /** + * Installs the reconciler on the given text viewer. After this method has been + * finished, the reconciler is operational, i.e., it works without requesting + * further client actions until <code>uninstall</code> is called. + * + * @param textViewer the viewer on which the reconciler is installed + */ + void install(ITextViewer textViewer); + + /** + * Removes the reconciler from the text viewer it has + * previously been installed on. + */ + void uninstall(); + + /** + * Returns the reconciling strategy registered with the reconciler + * for the specified content type. + * + * @param contentType the content type for which to determine the reconciling strategy + * @return the reconciling strategy registered for the given content type, or + * <code>null</code> if there is no such strategy + */ + IReconcilingStrategy getReconcilingStrategy(String contentType); +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/IReconcilingStrategy.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/IReconcilingStrategy.java new file mode 100644 index 000000000..b7f7a582a --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/reconciler/IReconcilingStrategy.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text.reconciler; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; + + +/** + * A reconciling strategy is used by an reconciler to reconcile a model + * based on text of a particular content type. It provides methods for + * incremental as well as non-incremental reconciling. + * <p> + * If a reconcile strategy consists of several steps between which + * model transformation is desired the each step should implement + * {@link org.eclipse.jface.text.reconciler.IReconcileStep}. + * </p> + * <p> + * In order to provide backward compatibility for clients of <code>IReconcilingStrategy</code>, extension + * interfaces are used to provide a means of evolution. The following extension interfaces exist: + * <ul> + * <li>{@link org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension} since version 2.0 introducing + * the following functions: + * <ul> + * <li>usage of a progress monitor</li> + * <li>initial reconciling step: if a reconciler runs as periodic activity in the background, this + * methods offers the reconciler a chance for initializing its strategies and achieving a + * reconciled state before the periodic activity starts.</li> + * </ul> + * </li> + * </ul> + * </p> + * <p> + * This interface must be implemented by clients. Implementers should be + * registered with a reconciler in order get involved in the reconciling + * process. + * </p> + */ +public interface IReconcilingStrategy { + + /** + * Tells this reconciling strategy on which document it will + * work. This method will be called before any other method + * and can be called multiple times. The regions passed to the + * other methods always refer to the most recent document + * passed into this method. + * + * @param document the document on which this strategy will work + */ + void setDocument(IDocument document); + + /** + * Activates incremental reconciling of the specified dirty region. + * As a dirty region might span multiple content types, the segment of the + * dirty region which should be investigated is also provided to this + * reconciling strategy. The given regions refer to the document passed into + * the most recent call of {@link #setDocument(IDocument)}. + * + * @param dirtyRegion the document region which has been changed + * @param subRegion the sub region in the dirty region which should be reconciled + */ + void reconcile(DirtyRegion dirtyRegion, IRegion subRegion); + + /** + * Activates non-incremental reconciling. The reconciling strategy is just told + * that there are changes and that it should reconcile the given partition of the + * document most recently passed into {@link #setDocument(IDocument)}. + * + * @param partition the document partition to be reconciled + */ + void reconcile(IRegion partition); +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/rules/DefaultDamagerRepairer.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/rules/DefaultDamagerRepairer.java new file mode 100644 index 000000000..4dccc48ed --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/rules/DefaultDamagerRepairer.java @@ -0,0 +1,231 @@ +/******************************************************************************* + * Copyright (c) 2000, 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text.rules; + + +import org.eclipse.fx.ui.controls.styledtext.StyleRange; +import org.eclipse.jface.text.Assert; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextAttribute; +import org.eclipse.jface.text.TextPresentation; +import org.eclipse.jface.text.presentation.IPresentationDamager; +import org.eclipse.jface.text.presentation.IPresentationRepairer; + + +/** + * A standard implementation of a syntax driven presentation damager + * and presentation repairer. It uses a token scanner to scan + * the document and to determine its damage and new text presentation. + * The tokens returned by the scanner are supposed to return text attributes + * as their data. + * + * @see ITokenScanner + * @since 2.0 + */ +public class DefaultDamagerRepairer implements IPresentationDamager, IPresentationRepairer { + + + /** The document this object works on */ + protected IDocument fDocument; + /** The scanner it uses */ + protected ITokenScanner fScanner; + /** The default text attribute if non is returned as data by the current token */ + protected TextAttribute fDefaultTextAttribute; + + /** + * Creates a damager/repairer that uses the given scanner and returns the given default + * text attribute if the current token does not carry a text attribute. + * + * @param scanner the token scanner to be used + * @param defaultTextAttribute the text attribute to be returned if non is specified by the current token, + * may not be <code>null</code> + * + * @deprecated use DefaultDamagerRepairer(ITokenScanner) instead + */ + public DefaultDamagerRepairer(ITokenScanner scanner, TextAttribute defaultTextAttribute) { + + Assert.isNotNull(defaultTextAttribute); + + fScanner= scanner; + fDefaultTextAttribute= defaultTextAttribute; + } + + /** + * Creates a damager/repairer that uses the given scanner. The scanner may not be <code>null</code> + * and is assumed to return only token that carry text attributes. + * + * @param scanner the token scanner to be used, may not be <code>null</code> + */ + public DefaultDamagerRepairer(ITokenScanner scanner) { + + Assert.isNotNull(scanner); + + fScanner= scanner; + fDefaultTextAttribute= new TextAttribute(null); + } + + /* + * @see IPresentationDamager#setDocument(IDocument) + * @see IPresentationRepairer#setDocument(IDocument) + */ + public void setDocument(IDocument document) { + fDocument= document; + } + + + //---- IPresentationDamager + + /** + * Returns the end offset of the line that contains the specified offset or + * if the offset is inside a line delimiter, the end offset of the next line. + * + * @param offset the offset whose line end offset must be computed + * @return the line end offset for the given offset + * @exception BadLocationException if offset is invalid in the current document + */ + protected int endOfLineOf(int offset) throws BadLocationException { + + IRegion info= fDocument.getLineInformationOfOffset(offset); + if (offset <= info.getOffset() + info.getLength()) + return info.getOffset() + info.getLength(); + + int line= fDocument.getLineOfOffset(offset); + try { + info= fDocument.getLineInformation(line + 1); + return info.getOffset() + info.getLength(); + } catch (BadLocationException x) { + return fDocument.getLength(); + } + } + + /** + * {@inheritDoc} + * <p> + * This implementation damages entire lines unless clipped by the given partition. + * </p> + * + * @return the full lines containing the document changes described by the document event, + * clipped by the given partition. If there was a partitioning change then the whole + * partition is returned. + */ + public IRegion getDamageRegion(ITypedRegion partition, DocumentEvent e, boolean documentPartitioningChanged) { + + if (!documentPartitioningChanged) { + try { + + IRegion info= fDocument.getLineInformationOfOffset(e.getOffset()); + int start= Math.max(partition.getOffset(), info.getOffset()); + + int end= e.getOffset() + (e.getText() == null ? e.getLength() : e.getText().length()); + + if (info.getOffset() <= end && end <= info.getOffset() + info.getLength()) { + // optimize the case of the same line + end= info.getOffset() + info.getLength(); + } else + end= endOfLineOf(end); + + end= Math.min(partition.getOffset() + partition.getLength(), end); + return new Region(start, end - start); + + } catch (BadLocationException x) { + } + } + + return partition; + } + + //---- IPresentationRepairer + + /* + * @see IPresentationRepairer#createPresentation(TextPresentation, ITypedRegion) + */ + public void createPresentation(TextPresentation presentation, ITypedRegion region) { + + if (fScanner == null) { + // will be removed if deprecated constructor will be removed + addRange(presentation, region.getOffset(), region.getLength(), fDefaultTextAttribute); + return; + } + + int lastStart= region.getOffset(); + int length= 0; + boolean firstToken= true; + IToken lastToken= Token.UNDEFINED; + TextAttribute lastAttribute= getTokenTextAttribute(lastToken); + + fScanner.setRange(fDocument, lastStart, region.getLength()); + + while (true) { + IToken token= fScanner.nextToken(); + if (token.isEOF()) + break; + + TextAttribute attribute= getTokenTextAttribute(token); + if (lastAttribute != null && lastAttribute.equals(attribute)) { + length += fScanner.getTokenLength(); + firstToken= false; + } else { + if (!firstToken) + addRange(presentation, lastStart, length, lastAttribute); + firstToken= false; + lastToken= token; + lastAttribute= attribute; + lastStart= fScanner.getTokenOffset(); + length= fScanner.getTokenLength(); + } + } + + addRange(presentation, lastStart, length, lastAttribute); + } + + /** + * Returns a text attribute encoded in the given token. If the token's + * data is not <code>null</code> and a text attribute it is assumed that + * it is the encoded text attribute. It returns the default text attribute + * if there is no encoded text attribute found. + * + * @param token the token whose text attribute is to be determined + * @return the token's text attribute + */ + protected TextAttribute getTokenTextAttribute(IToken token) { + Object data= token.getData(); + if (data instanceof TextAttribute) + return (TextAttribute) data; + return fDefaultTextAttribute; + } + + /** + * Adds style information to the given text presentation. + * + * @param presentation the text presentation to be extended + * @param offset the offset of the range to be styled + * @param length the length of the range to be styled + * @param attr the attribute describing the style of the range to be styled + */ + protected void addRange(TextPresentation presentation, int offset, int length, TextAttribute attr) { + if (attr != null) { + int style= attr.getStyle(); + int fontStyle= style & (StyleRange.ITALIC | StyleRange.BOLD | StyleRange.NORMAL); + StyleRange styleRange= new StyleRange(offset, length, attr.getForeground(), attr.getBackground(), fontStyle); + styleRange.strikeout= (style & TextAttribute.STRIKETHROUGH) != 0; + styleRange.underline= (style & TextAttribute.UNDERLINE) != 0; + styleRange.font= attr.getFont(); + presentation.addStyleRange(styleRange); + } + } +} + + diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewer.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewer.java new file mode 100644 index 000000000..9a1d8673d --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewer.java @@ -0,0 +1,7 @@ +package org.eclipse.jface.text.source; + +import org.eclipse.jface.text.ITextViewer; + +public interface ISourceViewer extends ITextViewer { + void configure(SourceViewerConfiguration configuration); +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension.java new file mode 100644 index 000000000..5fd1cd1ca --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension.java @@ -0,0 +1,5 @@ +package org.eclipse.jface.text.source; + +public interface ISourceViewerExtension { + +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension2.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension2.java new file mode 100644 index 000000000..925eef77e --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension2.java @@ -0,0 +1,5 @@ +package org.eclipse.jface.text.source; + +public interface ISourceViewerExtension2 { + +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension3.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension3.java new file mode 100644 index 000000000..495c4cbbb --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension3.java @@ -0,0 +1,5 @@ +package org.eclipse.jface.text.source; + +public interface ISourceViewerExtension3 { + +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension4.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension4.java new file mode 100644 index 000000000..f54fa74a8 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/ISourceViewerExtension4.java @@ -0,0 +1,5 @@ +package org.eclipse.jface.text.source; + +public interface ISourceViewerExtension4 { + +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/SourceViewer.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/SourceViewer.java new file mode 100644 index 000000000..561a7d108 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/SourceViewer.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2000, 2013 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Tom Eicher (Avaloq Evolution AG) - block selection mode + * Tom Hofmann (Perspectix AG) - bug 297572 + *******************************************************************************/ +package org.eclipse.jface.text.source; + +import org.eclipse.jface.text.TextViewer; +import org.eclipse.jface.text.presentation.IPresentationReconciler; +import org.eclipse.jface.text.reconciler.IReconciler; + +public class SourceViewer extends TextViewer implements ISourceViewer, ISourceViewerExtension, ISourceViewerExtension2, ISourceViewerExtension3, ISourceViewerExtension4 { + + private IPresentationReconciler fPresentationReconciler; + private IReconciler fReconciler; + + @Override + public void configure(SourceViewerConfiguration configuration) { + if (getTextWidget() == null) + return; + + setDocumentPartitioning(configuration.getConfiguredDocumentPartitioning(this)); + + // install content type independent plug-ins + fPresentationReconciler= configuration.getPresentationReconciler(this); + if (fPresentationReconciler != null) + fPresentationReconciler.install(this); + + fReconciler= configuration.getReconciler(this); + if (fReconciler != null) + fReconciler.install(this); + } + +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/SourceViewerConfiguration.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/SourceViewerConfiguration.java new file mode 100644 index 000000000..6de5d43db --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/text/source/SourceViewerConfiguration.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2000, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text.source; + +import org.eclipse.jface.text.IDocumentExtension3; +import org.eclipse.jface.text.presentation.IPresentationReconciler; +import org.eclipse.jface.text.presentation.PresentationReconciler; +import org.eclipse.jface.text.reconciler.IReconciler; + +public class SourceViewerConfiguration { + public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) { + return IDocumentExtension3.DEFAULT_PARTITIONING; + } + + public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) { + PresentationReconciler reconciler= new PresentationReconciler(); + reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer)); + return reconciler; + } + + public IReconciler getReconciler(ISourceViewer sourceViewer) { + return null; + } +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/viewers/IInputSelectionProvider.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/viewers/IInputSelectionProvider.java new file mode 100644 index 000000000..34de0cd52 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/viewers/IInputSelectionProvider.java @@ -0,0 +1,5 @@ +package org.eclipse.jface.viewers; + +public interface IInputSelectionProvider { + public Object getInput(); +} diff --git a/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/viewers/Viewer.java b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/viewers/Viewer.java new file mode 100644 index 000000000..6f8160dd0 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text.ui/src/org/eclipse/jface/viewers/Viewer.java @@ -0,0 +1,10 @@ +package org.eclipse.jface.viewers; + +import javafx.scene.layout.AnchorPane; + +public abstract class Viewer extends AnchorPane { + protected void inputChanged(Object input, Object oldInput) { + } + + public abstract void setInput(Object input); +} diff --git a/experimental/compensator/org.eclipse.fx.text/.classpath b/experimental/compensator/org.eclipse.fx.text/.classpath new file mode 100644 index 000000000..eca7bdba8 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/experimental/compensator/org.eclipse.fx.text/.gitignore b/experimental/compensator/org.eclipse.fx.text/.gitignore new file mode 100644 index 000000000..ae3c17260 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/experimental/compensator/org.eclipse.fx.text/.project b/experimental/compensator/org.eclipse.fx.text/.project new file mode 100644 index 000000000..bef853f43 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.fx.text</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/experimental/compensator/org.eclipse.fx.text/.settings/org.eclipse.jdt.core.prefs b/experimental/compensator/org.eclipse.fx.text/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..0c68a61dc --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/experimental/compensator/org.eclipse.fx.text/META-INF/MANIFEST.MF b/experimental/compensator/org.eclipse.fx.text/META-INF/MANIFEST.MF new file mode 100644 index 000000000..202af9645 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/META-INF/MANIFEST.MF @@ -0,0 +1,46 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Text +Bundle-SymbolicName: org.eclipse.fx.text +Bundle-Version: 1.0.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Export-Package: org.eclipse.jface.text, + org.eclipse.jface.text.rules +Require-Bundle: org.eclipse.text;bundle-version="3.5.300", + org.eclipse.equinox.common;bundle-version="3.6.200", + org.eclipse.core.runtime;bundle-version="3.10.0" +Import-Package: javafx.animation;version="2.2.0", + javafx.application;version="2.2.0", + javafx.beans;version="2.2.0", + javafx.beans.binding;version="2.2.0", + javafx.beans.property;version="2.2.0", + javafx.beans.property.adapter;version="2.2.0", + javafx.beans.value;version="2.2.0", + javafx.collections;version="2.2.0", + javafx.collections.transformation;version="8.0.0", + javafx.concurrent;version="2.2.0", + javafx.css;version="8.0.0", + javafx.embed.swing;version="2.2.0", + javafx.embed.swt;version="2.2.0", + javafx.event;version="2.2.0", + javafx.fxml;version="2.2.0", + javafx.geometry;version="2.2.0", + javafx.print;version="8.0.0", + javafx.scene;version="2.2.0", + javafx.scene.canvas;version="2.2.0", + javafx.scene.chart;version="2.2.0", + javafx.scene.control;version="2.2.0", + javafx.scene.control.cell;version="2.2.0", + javafx.scene.effect;version="2.2.0", + javafx.scene.image;version="2.2.0", + javafx.scene.input;version="2.2.0", + javafx.scene.layout;version="2.2.0", + javafx.scene.media;version="2.2.0", + javafx.scene.paint;version="2.2.0", + javafx.scene.shape;version="2.2.0", + javafx.scene.text;version="2.2.0", + javafx.scene.transform;version="2.2.0", + javafx.scene.web;version="2.2.0", + javafx.stage;version="2.2.0", + javafx.util;version="2.2.0", + javafx.util.converter;version="2.2.0" diff --git a/experimental/compensator/org.eclipse.fx.text/build.properties b/experimental/compensator/org.eclipse.fx.text/build.properties new file mode 100644 index 000000000..34d2e4d2d --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/DocumentClone.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/DocumentClone.java new file mode 100644 index 000000000..2998f1e6d --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/DocumentClone.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text; + +import org.eclipse.core.runtime.Assert; + + +/** + * An {@link org.eclipse.jface.text.IDocument} that is a read-only clone of another document. + * + * @since 3.0 + */ +class DocumentClone extends AbstractDocument { + + private static class StringTextStore implements ITextStore { + + private String fContent; + + /** + * Creates a new string text store with the given content. + * + * @param content the content + */ + public StringTextStore(String content) { + Assert.isNotNull(content); + fContent= content; + } + + /* + * @see org.eclipse.jface.text.ITextStore#get(int) + */ + public char get(int offset) { + return fContent.charAt(offset); + } + + /* + * @see org.eclipse.jface.text.ITextStore#get(int, int) + */ + public String get(int offset, int length) { + return fContent.substring(offset, offset + length); + } + + /* + * @see org.eclipse.jface.text.ITextStore#getLength() + */ + public int getLength() { + return fContent.length(); + } + + /* + * @see org.eclipse.jface.text.ITextStore#replace(int, int, java.lang.String) + */ + public void replace(int offset, int length, String text) { + } + + /* + * @see org.eclipse.jface.text.ITextStore#set(java.lang.String) + */ + public void set(String text) { + } + + } + + /** + * Creates a new document clone with the given content. + * + * @param content the content + * @param lineDelimiters the line delimiters + */ + public DocumentClone(String content, String[] lineDelimiters) { + super(); + setTextStore(new StringTextStore(content)); + ConfigurableLineTracker tracker= new ConfigurableLineTracker(lineDelimiters); + setLineTracker(tracker); + getTracker().set(content); + completeInitialization(); + } +} diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/BufferedRuleBasedScanner.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/BufferedRuleBasedScanner.java new file mode 100644 index 000000000..6f804a832 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/BufferedRuleBasedScanner.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2000, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.jface.text.rules; + +import org.eclipse.core.runtime.Assert; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; + +/** + * A buffered rule based scanner. The buffer always contains a section + * of a fixed size of the document to be scanned. Completely adheres to + * the contract of <code>RuleBasedScanner</code>. + */ +public class BufferedRuleBasedScanner extends RuleBasedScanner { + + /** The default buffer size. Value = 500 */ + private final static int DEFAULT_BUFFER_SIZE= 500; + /** The actual size of the buffer. Initially set to <code>DEFAULT_BUFFER_SIZE</code> */ + private int fBufferSize= DEFAULT_BUFFER_SIZE; + /** The buffer */ + private char[] fBuffer= new char[DEFAULT_BUFFER_SIZE]; + /** The offset of the document at which the buffer starts */ + private int fStart; + /** The offset of the document at which the buffer ends */ + private int fEnd; + /** The cached length of the document */ + private int fDocumentLength; + + + /** + * Creates a new buffered rule based scanner which does + * not have any rule and a default buffer size of 500 characters. + */ + protected BufferedRuleBasedScanner() { + super(); + } + + /** + * Creates a new buffered rule based scanner which does + * not have any rule. The buffer size is set to the given + * number of characters. + * + * @param size the buffer size + */ + public BufferedRuleBasedScanner(int size) { + super(); + setBufferSize(size); + } + + /** + * Sets the buffer to the given number of characters. + * + * @param size the buffer size + */ + protected void setBufferSize(int size) { + Assert.isTrue(size > 0); + fBufferSize= size; + fBuffer= new char[size]; + } + + /** + * Shifts the buffer so that the buffer starts at the + * given document offset. + * + * @param offset the document offset at which the buffer starts + */ + private void shiftBuffer(int offset) { + + fStart= offset; + fEnd= fStart + fBufferSize; + if (fEnd > fDocumentLength) + fEnd= fDocumentLength; + + try { + + String content= fDocument.get(fStart, fEnd - fStart); + content.getChars(0, fEnd - fStart, fBuffer, 0); + + } catch (BadLocationException x) { + } + } + + /* + * @see RuleBasedScanner#setRange(IDocument, int, int) + */ + public void setRange(IDocument document, int offset, int length) { + + super.setRange(document, offset, length); + + fDocumentLength= document.getLength(); + shiftBuffer(offset); + } + + /* + * @see RuleBasedScanner#read() + */ + public int read() { + fColumn= UNDEFINED; + if (fOffset >= fRangeEnd) { + ++ fOffset; + return EOF; + } + + if (fOffset == fEnd) + shiftBuffer(fEnd); + else if (fOffset < fStart || fEnd < fOffset) + shiftBuffer(fOffset); + + return fBuffer[fOffset++ - fStart]; + } + + /* + * @see RuleBasedScanner#unread() + */ + public void unread() { + + if (fOffset == fStart) + shiftBuffer(Math.max(0, fStart - (fBufferSize / 2))); + + --fOffset; + fColumn= UNDEFINED; + } +} + + diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/FastPartitioner.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/FastPartitioner.java new file mode 100644 index 000000000..df08dd407 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/FastPartitioner.java @@ -0,0 +1,822 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text.rules; + + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.Platform; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.BadPositionCategoryException; +import org.eclipse.jface.text.DefaultPositionUpdater; +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.DocumentRewriteSession; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentPartitioner; +import org.eclipse.jface.text.IDocumentPartitionerExtension; +import org.eclipse.jface.text.IDocumentPartitionerExtension2; +import org.eclipse.jface.text.IDocumentPartitionerExtension3; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextUtilities; +import org.eclipse.jface.text.TypedPosition; +import org.eclipse.jface.text.TypedRegion; + + + +/** + * A standard implementation of a document partitioner. It uses an + * {@link IPartitionTokenScanner} to scan the document and to determine the + * document's partitioning. The tokens returned by the scanner must return the + * partition type as their data. The partitioner remembers the document's + * partitions in the document itself rather than maintaining its own data + * structure. + * <p> + * To reduce array creations in {@link IDocument#getPositions(String)}, the + * positions get cached. The cache is cleared after updating the positions in + * {@link #documentChanged2(DocumentEvent)}. Subclasses need to call + * {@link #clearPositionCache()} after modifying the partitioner's positions. + * The cached positions may be accessed through {@link #getPositions()}. + * </p> + * + * @see IPartitionTokenScanner + * @since 3.1 + */ +public class FastPartitioner implements IDocumentPartitioner, IDocumentPartitionerExtension, IDocumentPartitionerExtension2, IDocumentPartitionerExtension3 { + + /** + * The position category this partitioner uses to store the document's partitioning information. + */ + private static final String CONTENT_TYPES_CATEGORY= "__content_types_category"; //$NON-NLS-1$ + /** The partitioner's scanner */ + protected final IPartitionTokenScanner fScanner; + /** The legal content types of this partitioner */ + protected final String[] fLegalContentTypes; + /** The partitioner's document */ + protected IDocument fDocument; + /** The document length before a document change occurred */ + protected int fPreviousDocumentLength; + /** The position updater used to for the default updating of partitions */ + protected final DefaultPositionUpdater fPositionUpdater; + /** The offset at which the first changed partition starts */ + protected int fStartOffset; + /** The offset at which the last changed partition ends */ + protected int fEndOffset; + /**The offset at which a partition has been deleted */ + protected int fDeleteOffset; + /** + * The position category this partitioner uses to store the document's partitioning information. + */ + private final String fPositionCategory; + /** + * The active document rewrite session. + */ + private DocumentRewriteSession fActiveRewriteSession; + /** + * Flag indicating whether this partitioner has been initialized. + */ + private boolean fIsInitialized= false; + /** + * The cached positions from our document, so we don't create a new array every time + * someone requests partition information. + */ + private Position[] fCachedPositions= null; + /** Debug option for cache consistency checking. */ + private static final boolean CHECK_CACHE_CONSISTENCY= "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jface.text/debug/FastPartitioner/PositionCache")); //$NON-NLS-1$//$NON-NLS-2$; + + /** + * Creates a new partitioner that uses the given scanner and may return + * partitions of the given legal content types. + * + * @param scanner the scanner this partitioner is supposed to use + * @param legalContentTypes the legal content types of this partitioner + */ + public FastPartitioner(IPartitionTokenScanner scanner, String[] legalContentTypes) { + fScanner= scanner; + fLegalContentTypes= TextUtilities.copy(legalContentTypes); + fPositionCategory= CONTENT_TYPES_CATEGORY + hashCode(); + fPositionUpdater= new DefaultPositionUpdater(fPositionCategory); + } + + /* + * @see org.eclipse.jface.text.IDocumentPartitionerExtension2#getManagingPositionCategories() + */ + public String[] getManagingPositionCategories() { + return new String[] { fPositionCategory }; + } + + /* + * @see org.eclipse.jface.text.IDocumentPartitioner#connect(org.eclipse.jface.text.IDocument) + */ + public final void connect(IDocument document) { + connect(document, false); + } + + /** + * {@inheritDoc} + * <p> + * May be extended by subclasses. + * </p> + */ + public void connect(IDocument document, boolean delayInitialization) { + Assert.isNotNull(document); + Assert.isTrue(!document.containsPositionCategory(fPositionCategory)); + + fDocument= document; + fDocument.addPositionCategory(fPositionCategory); + + fIsInitialized= false; + if (!delayInitialization) + checkInitialization(); + } + + /** + * Calls {@link #initialize()} if the receiver is not yet initialized. + */ + protected final void checkInitialization() { + if (!fIsInitialized) + initialize(); + } + + /** + * Performs the initial partitioning of the partitioner's document. + * <p> + * May be extended by subclasses. + * </p> + */ + protected void initialize() { + fIsInitialized= true; + clearPositionCache(); + fScanner.setRange(fDocument, 0, fDocument.getLength()); + + try { + IToken token= fScanner.nextToken(); + while (!token.isEOF()) { + + String contentType= getTokenContentType(token); + + if (isSupportedContentType(contentType)) { + TypedPosition p= new TypedPosition(fScanner.getTokenOffset(), fScanner.getTokenLength(), contentType); + fDocument.addPosition(fPositionCategory, p); + } + + token= fScanner.nextToken(); + } + } catch (BadLocationException x) { + // cannot happen as offsets come from scanner + } catch (BadPositionCategoryException x) { + // cannot happen if document has been connected before + } + } + + /** + * {@inheritDoc} + * <p> + * May be extended by subclasses. + * </p> + */ + public void disconnect() { + + Assert.isTrue(fDocument.containsPositionCategory(fPositionCategory)); + + try { + fDocument.removePositionCategory(fPositionCategory); + } catch (BadPositionCategoryException x) { + // can not happen because of Assert + } + } + + /** + * {@inheritDoc} + * <p> + * May be extended by subclasses. + * </p> + */ + public void documentAboutToBeChanged(DocumentEvent e) { + if (fIsInitialized) { + + Assert.isTrue(e.getDocument() == fDocument); + + fPreviousDocumentLength= e.getDocument().getLength(); + fStartOffset= -1; + fEndOffset= -1; + fDeleteOffset= -1; + } + } + + /* + * @see IDocumentPartitioner#documentChanged(DocumentEvent) + */ + public final boolean documentChanged(DocumentEvent e) { + if (fIsInitialized) { + IRegion region= documentChanged2(e); + return (region != null); + } + return false; + } + + /** + * Helper method for tracking the minimal region containing all partition changes. + * If <code>offset</code> is smaller than the remembered offset, <code>offset</code> + * will from now on be remembered. If <code>offset + length</code> is greater than + * the remembered end offset, it will be remembered from now on. + * + * @param offset the offset + * @param length the length + */ + private void rememberRegion(int offset, int length) { + // remember start offset + if (fStartOffset == -1) + fStartOffset= offset; + else if (offset < fStartOffset) + fStartOffset= offset; + + // remember end offset + int endOffset= offset + length; + if (fEndOffset == -1) + fEndOffset= endOffset; + else if (endOffset > fEndOffset) + fEndOffset= endOffset; + } + + /** + * Remembers the given offset as the deletion offset. + * + * @param offset the offset + */ + private void rememberDeletedOffset(int offset) { + fDeleteOffset= offset; + } + + /** + * Creates the minimal region containing all partition changes using the + * remembered offset, end offset, and deletion offset. + * + * @return the minimal region containing all the partition changes + */ + private IRegion createRegion() { + if (fDeleteOffset == -1) { + if (fStartOffset == -1 || fEndOffset == -1) + return null; + return new Region(fStartOffset, fEndOffset - fStartOffset); + } else if (fStartOffset == -1 || fEndOffset == -1) { + return new Region(fDeleteOffset, 0); + } else { + int offset= Math.min(fDeleteOffset, fStartOffset); + int endOffset= Math.max(fDeleteOffset, fEndOffset); + return new Region(offset, endOffset - offset); + } + } + + /** + * {@inheritDoc} + * <p> + * May be extended by subclasses. + * </p> + */ + public IRegion documentChanged2(DocumentEvent e) { + + if (!fIsInitialized) + return null; + + try { + Assert.isTrue(e.getDocument() == fDocument); + + Position[] category= getPositions(); + IRegion line= fDocument.getLineInformationOfOffset(e.getOffset()); + int reparseStart= line.getOffset(); + int partitionStart= -1; + String contentType= null; + int newLength= e.getText() == null ? 0 : e.getText().length(); + + int first= fDocument.computeIndexInCategory(fPositionCategory, reparseStart); + if (first > 0) { + TypedPosition partition= (TypedPosition) category[first - 1]; + if (partition.includes(reparseStart)) { + partitionStart= partition.getOffset(); + contentType= partition.getType(); + if (e.getOffset() == partition.getOffset() + partition.getLength()) + reparseStart= partitionStart; + -- first; + } else if (reparseStart == e.getOffset() && reparseStart == partition.getOffset() + partition.getLength()) { + partitionStart= partition.getOffset(); + contentType= partition.getType(); + reparseStart= partitionStart; + -- first; + } else { + partitionStart= partition.getOffset() + partition.getLength(); + contentType= IDocument.DEFAULT_CONTENT_TYPE; + } + } + + fPositionUpdater.update(e); + for (int i= first; i < category.length; i++) { + Position p= category[i]; + if (p.isDeleted) { + rememberDeletedOffset(e.getOffset()); + break; + } + } + clearPositionCache(); + category= getPositions(); + + fScanner.setPartialRange(fDocument, reparseStart, fDocument.getLength() - reparseStart, contentType, partitionStart); + + int behindLastScannedPosition= reparseStart; + IToken token= fScanner.nextToken(); + + while (!token.isEOF()) { + + contentType= getTokenContentType(token); + + if (!isSupportedContentType(contentType)) { + token= fScanner.nextToken(); + continue; + } + + int start= fScanner.getTokenOffset(); + int length= fScanner.getTokenLength(); + + behindLastScannedPosition= start + length; + int lastScannedPosition= behindLastScannedPosition - 1; + + // remove all affected positions + while (first < category.length) { + TypedPosition p= (TypedPosition) category[first]; + if (lastScannedPosition >= p.offset + p.length || + (p.overlapsWith(start, length) && + (!fDocument.containsPosition(fPositionCategory, start, length) || + !contentType.equals(p.getType())))) { + + rememberRegion(p.offset, p.length); + fDocument.removePosition(fPositionCategory, p); + ++ first; + + } else + break; + } + + // if position already exists and we have scanned at least the + // area covered by the event, we are done + if (fDocument.containsPosition(fPositionCategory, start, length)) { + if (lastScannedPosition >= e.getOffset() + newLength) + return createRegion(); + ++ first; + } else { + // insert the new type position + try { + fDocument.addPosition(fPositionCategory, new TypedPosition(start, length, contentType)); + rememberRegion(start, length); + } catch (BadPositionCategoryException x) { + } catch (BadLocationException x) { + } + } + + token= fScanner.nextToken(); + } + + first= fDocument.computeIndexInCategory(fPositionCategory, behindLastScannedPosition); + + clearPositionCache(); + category= getPositions(); + TypedPosition p; + while (first < category.length) { + p= (TypedPosition) category[first++]; + fDocument.removePosition(fPositionCategory, p); + rememberRegion(p.offset, p.length); + } + + } catch (BadPositionCategoryException x) { + // should never happen on connected documents + } catch (BadLocationException x) { + } finally { + clearPositionCache(); + } + + return createRegion(); + } + + /** + * Returns the position in the partitoner's position category which is + * close to the given offset. This is, the position has either an offset which + * is the same as the given offset or an offset which is smaller than the given + * offset. This method profits from the knowledge that a partitioning is + * a ordered set of disjoint position. + * <p> + * May be extended or replaced by subclasses. + * </p> + * @param offset the offset for which to search the closest position + * @return the closest position in the partitioner's category + */ + protected TypedPosition findClosestPosition(int offset) { + + try { + + int index= fDocument.computeIndexInCategory(fPositionCategory, offset); + Position[] category= getPositions(); + + if (category.length == 0) + return null; + + if (index < category.length) { + if (offset == category[index].offset) + return (TypedPosition) category[index]; + } + + if (index > 0) + index--; + + return (TypedPosition) category[index]; + + } catch (BadPositionCategoryException x) { + } catch (BadLocationException x) { + } + + return null; + } + + + /** + * {@inheritDoc} + * <p> + * May be replaced or extended by subclasses. + * </p> + */ + public String getContentType(int offset) { + checkInitialization(); + + TypedPosition p= findClosestPosition(offset); + if (p != null && p.includes(offset)) + return p.getType(); + + return IDocument.DEFAULT_CONTENT_TYPE; + } + + /** + * {@inheritDoc} + * <p> + * May be replaced or extended by subclasses. + * </p> + */ + public ITypedRegion getPartition(int offset) { + checkInitialization(); + + try { + + Position[] category = getPositions(); + + if (category == null || category.length == 0) + return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE); + + int index= fDocument.computeIndexInCategory(fPositionCategory, offset); + + if (index < category.length) { + + TypedPosition next= (TypedPosition) category[index]; + + if (offset == next.offset) + return new TypedRegion(next.getOffset(), next.getLength(), next.getType()); + + if (index == 0) + return new TypedRegion(0, next.offset, IDocument.DEFAULT_CONTENT_TYPE); + + TypedPosition previous= (TypedPosition) category[index - 1]; + if (previous.includes(offset)) + return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType()); + + int endOffset= previous.getOffset() + previous.getLength(); + return new TypedRegion(endOffset, next.getOffset() - endOffset, IDocument.DEFAULT_CONTENT_TYPE); + } + + TypedPosition previous= (TypedPosition) category[category.length - 1]; + if (previous.includes(offset)) + return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType()); + + int endOffset= previous.getOffset() + previous.getLength(); + return new TypedRegion(endOffset, fDocument.getLength() - endOffset, IDocument.DEFAULT_CONTENT_TYPE); + + } catch (BadPositionCategoryException x) { + } catch (BadLocationException x) { + } + + return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE); + } + + /* + * @see IDocumentPartitioner#computePartitioning(int, int) + */ + public final ITypedRegion[] computePartitioning(int offset, int length) { + return computePartitioning(offset, length, false); + } + + /** + * {@inheritDoc} + * <p> + * May be replaced or extended by subclasses. + * </p> + */ + public String[] getLegalContentTypes() { + return TextUtilities.copy(fLegalContentTypes); + } + + /** + * Returns whether the given type is one of the legal content types. + * <p> + * May be extended by subclasses. + * </p> + * + * @param contentType the content type to check + * @return <code>true</code> if the content type is a legal content type + */ + protected boolean isSupportedContentType(String contentType) { + if (contentType != null) { + for (int i= 0; i < fLegalContentTypes.length; i++) { + if (fLegalContentTypes[i].equals(contentType)) + return true; + } + } + + return false; + } + + /** + * Returns a content type encoded in the given token. If the token's + * data is not <code>null</code> and a string it is assumed that + * it is the encoded content type. + * <p> + * May be replaced or extended by subclasses. + * </p> + * + * @param token the token whose content type is to be determined + * @return the token's content type + */ + protected String getTokenContentType(IToken token) { + Object data= token.getData(); + if (data instanceof String) + return (String) data; + return null; + } + + /* zero-length partition support */ + + /** + * {@inheritDoc} + * <p> + * May be replaced or extended by subclasses. + * </p> + */ + public String getContentType(int offset, boolean preferOpenPartitions) { + return getPartition(offset, preferOpenPartitions).getType(); + } + + /** + * {@inheritDoc} + * <p> + * May be replaced or extended by subclasses. + * </p> + */ + public ITypedRegion getPartition(int offset, boolean preferOpenPartitions) { + ITypedRegion region= getPartition(offset); + if (preferOpenPartitions) { + if (region.getOffset() == offset && !region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) { + if (offset > 0) { + region= getPartition(offset - 1); + if (region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) + return region; + } + return new TypedRegion(offset, 0, IDocument.DEFAULT_CONTENT_TYPE); + } + } + return region; + } + + /** + * {@inheritDoc} + * <p> + * May be replaced or extended by subclasses. + * </p> + */ + public ITypedRegion[] computePartitioning(int offset, int length, boolean includeZeroLengthPartitions) { + checkInitialization(); + List list= new ArrayList(); + + try { + + int endOffset= offset + length; + + Position[] category= getPositions(); + + TypedPosition previous= null, current= null; + int start, end, gapOffset; + Position gap= new Position(0); + + int startIndex= getFirstIndexEndingAfterOffset(category, offset); + int endIndex= getFirstIndexStartingAfterOffset(category, endOffset); + for (int i= startIndex; i < endIndex; i++) { + + current= (TypedPosition) category[i]; + + gapOffset= (previous != null) ? previous.getOffset() + previous.getLength() : 0; + gap.setOffset(gapOffset); + gap.setLength(current.getOffset() - gapOffset); + if ((includeZeroLengthPartitions && overlapsOrTouches(gap, offset, length)) || + (gap.getLength() > 0 && gap.overlapsWith(offset, length))) { + start= Math.max(offset, gapOffset); + end= Math.min(endOffset, gap.getOffset() + gap.getLength()); + list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE)); + } + + if (current.overlapsWith(offset, length)) { + start= Math.max(offset, current.getOffset()); + end= Math.min(endOffset, current.getOffset() + current.getLength()); + list.add(new TypedRegion(start, end - start, current.getType())); + } + + previous= current; + } + + if (previous != null) { + gapOffset= previous.getOffset() + previous.getLength(); + gap.setOffset(gapOffset); + gap.setLength(fDocument.getLength() - gapOffset); + if ((includeZeroLengthPartitions && overlapsOrTouches(gap, offset, length)) || + (gap.getLength() > 0 && gap.overlapsWith(offset, length))) { + start= Math.max(offset, gapOffset); + end= Math.min(endOffset, fDocument.getLength()); + list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE)); + } + } + + if (list.isEmpty()) + list.add(new TypedRegion(offset, length, IDocument.DEFAULT_CONTENT_TYPE)); + + } catch (BadPositionCategoryException ex) { + // Make sure we clear the cache + clearPositionCache(); + } catch (RuntimeException ex) { + // Make sure we clear the cache + clearPositionCache(); + throw ex; + } + + TypedRegion[] result= new TypedRegion[list.size()]; + list.toArray(result); + return result; + } + + /** + * Returns <code>true</code> if the given ranges overlap with or touch each other. + * + * @param gap the first range + * @param offset the offset of the second range + * @param length the length of the second range + * @return <code>true</code> if the given ranges overlap with or touch each other + */ + private boolean overlapsOrTouches(Position gap, int offset, int length) { + return gap.getOffset() <= offset + length && offset <= gap.getOffset() + gap.getLength(); + } + + /** + * Returns the index of the first position which ends after the given offset. + * + * @param positions the positions in linear order + * @param offset the offset + * @return the index of the first position which ends after the offset + */ + private int getFirstIndexEndingAfterOffset(Position[] positions, int offset) { + int i= -1, j= positions.length; + while (j - i > 1) { + int k= (i + j) >> 1; + Position p= positions[k]; + if (p.getOffset() + p.getLength() > offset) + j= k; + else + i= k; + } + return j; + } + + /** + * Returns the index of the first position which starts at or after the given offset. + * + * @param positions the positions in linear order + * @param offset the offset + * @return the index of the first position which starts after the offset + */ + private int getFirstIndexStartingAfterOffset(Position[] positions, int offset) { + int i= -1, j= positions.length; + while (j - i > 1) { + int k= (i + j) >> 1; + Position p= positions[k]; + if (p.getOffset() >= offset) + j= k; + else + i= k; + } + return j; + } + + /* + * @see org.eclipse.jface.text.IDocumentPartitionerExtension3#startRewriteSession(org.eclipse.jface.text.DocumentRewriteSession) + */ + public void startRewriteSession(DocumentRewriteSession session) throws IllegalStateException { + if (fActiveRewriteSession != null) + throw new IllegalStateException(); + fActiveRewriteSession= session; + } + + /** + * {@inheritDoc} + * <p> + * May be extended by subclasses. + * </p> + */ + public void stopRewriteSession(DocumentRewriteSession session) { + if (fActiveRewriteSession == session) + flushRewriteSession(); + } + + /** + * {@inheritDoc} + * <p> + * May be extended by subclasses. + * </p> + */ + public DocumentRewriteSession getActiveRewriteSession() { + return fActiveRewriteSession; + } + + /** + * Flushes the active rewrite session. + */ + protected final void flushRewriteSession() { + fActiveRewriteSession= null; + + // remove all position belonging to the partitioner position category + try { + fDocument.removePositionCategory(fPositionCategory); + } catch (BadPositionCategoryException x) { + } + fDocument.addPositionCategory(fPositionCategory); + + fIsInitialized= false; + } + + /** + * Clears the position cache. Needs to be called whenever the positions have + * been updated. + */ + protected final void clearPositionCache() { + if (fCachedPositions != null) { + fCachedPositions= null; + } + } + + /** + * Returns the partitioners positions. + * + * @return the partitioners positions + * @throws BadPositionCategoryException if getting the positions from the + * document fails + */ + protected final Position[] getPositions() throws BadPositionCategoryException { + if (fCachedPositions == null) { + fCachedPositions= fDocument.getPositions(fPositionCategory); + } else if (CHECK_CACHE_CONSISTENCY) { + Position[] positions= fDocument.getPositions(fPositionCategory); + int len= Math.min(positions.length, fCachedPositions.length); + for (int i= 0; i < len; i++) { + if (!positions[i].equals(fCachedPositions[i])) + System.err.println("FastPartitioner.getPositions(): cached position is not up to date: from document: " + toString(positions[i]) + " in cache: " + toString(fCachedPositions[i])); //$NON-NLS-1$ //$NON-NLS-2$ + } + for (int i= len; i < positions.length; i++) + System.err.println("FastPartitioner.getPositions(): new position in document: " + toString(positions[i])); //$NON-NLS-1$ + for (int i= len; i < fCachedPositions.length; i++) + System.err.println("FastPartitioner.getPositions(): stale position in cache: " + toString(fCachedPositions[i])); //$NON-NLS-1$ + } + return fCachedPositions; + } + + /** + * Pretty print a <code>Position</code>. + * + * @param position the position to format + * @return a formatted string + */ + private String toString(Position position) { + return "P[" + position.getOffset() + "+" + position.getLength() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } +} diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/ICharacterScanner.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/ICharacterScanner.java new file mode 100644 index 000000000..97e8b4c71 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/ICharacterScanner.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text.rules; + + +/** + * Defines the interface of a character scanner used by rules. + * Rules may request the next character or ask the character + * scanner to unread the last read character. + */ +public interface ICharacterScanner { + + /** + * The value returned when this scanner has read EOF. + */ + public static final int EOF= -1; + + /** + * Provides rules access to the legal line delimiters. The returned + * object may not be modified by clients. + * + * @return the legal line delimiters + */ + char[][] getLegalLineDelimiters(); + + /** + * Returns the column of the character scanner. + * + * @return the column of the character scanner + */ + int getColumn(); + + /** + * Returns the next character or EOF if end of file has been reached + * + * @return the next character or EOF + */ + int read(); + + /** + * Rewinds the scanner before the last read character. + */ + void unread(); +} diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IPartitionTokenScanner.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IPartitionTokenScanner.java new file mode 100644 index 000000000..f0d2ebd2f --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IPartitionTokenScanner.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2000, 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.jface.text.rules; + + +import org.eclipse.jface.text.IDocument; + + +/** + * A partition token scanner returns tokens that represent partitions. For that reason, + * a partition token scanner is vulnerable in respect to the document offset it starts + * scanning. In a simple case, a partition token scanner must always start at a partition + * boundary. A partition token scanner can also start in the middle of a partition, + * if it knows the type of the partition. + * + * @since 2.0 + */ +public interface IPartitionTokenScanner extends ITokenScanner { + + /** + * Configures the scanner by providing access to the document range that should be scanned. The + * range may not only contain complete partitions but starts at the beginning of a line in the + * middle of a partition of the given content type. This requires that a partition delimiter can + * not contain a line delimiter. + * + * @param document the document to scan + * @param offset the offset of the document range to scan + * @param length the length of the document range to scan + * @param contentType the content type at the given offset + * @param partitionOffset the offset at which the partition of the given offset starts + */ + void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset); +} diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IPredicateRule.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IPredicateRule.java new file mode 100644 index 000000000..5a793437a --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IPredicateRule.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.jface.text.rules; + +/** + * Defines the interface for a rule used in the scanning of text for the purpose of + * document partitioning or text styling. A predicate rule can only return one single + * token after having successfully detected content. This token is called success token. + * Also, it also returns a token indicating that this rule has not been successful. + * + * @see ICharacterScanner + * @since 2.0 + */ +public interface IPredicateRule extends IRule { + + /** + * Returns the success token of this predicate rule. + * + * @return the success token of this rule + */ + IToken getSuccessToken(); + + /** + * Evaluates the rule by examining the characters available from + * the provided character scanner. The token returned by this rule + * returns <code>true</code> when calling <code>isUndefined</code>, + * if the text that the rule investigated does not match the rule's requirements. Otherwise, + * this method returns this rule's success token. If this rules relies on a text pattern + * comprising a opening and a closing character sequence this method can also be called + * when the scanner is positioned already between the opening and the closing sequence. + * In this case, <code>resume</code> must be set to <code>true</code>. + * + * @param scanner the character scanner to be used by this rule + * @param resume indicates that the rule starts working between the opening and the closing character sequence + * @return the token computed by the rule + */ + IToken evaluate(ICharacterScanner scanner, boolean resume); +} diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IRule.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IRule.java new file mode 100644 index 000000000..667de4689 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IRule.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2000, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text.rules; + + +/** + * Defines the interface for a rule used in the scanning of text for the purpose of document + * partitioning or text styling. + * + * @see ICharacterScanner + */ +public interface IRule { + + /** + * Evaluates the rule by examining the characters available from the provided character scanner. + * The token returned by this rule returns <code>true</code> when calling + * <code>isUndefined</code>, if the text that the rule investigated does not match the rule's + * requirements + * + * @param scanner the character scanner to be used by this rule + * @return the token computed by the rule + */ + IToken evaluate(ICharacterScanner scanner); +} diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IToken.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IToken.java new file mode 100644 index 000000000..4502569c0 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IToken.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text.rules; + + +/** + * A token to be returned by a rule. + */ +public interface IToken { + + /** + * Return whether this token is undefined. + * + * @return <code>true</code>if this token is undefined + */ + boolean isUndefined(); + + /** + * Return whether this token represents a whitespace. + * + * @return <code>true</code>if this token represents a whitespace + */ + boolean isWhitespace(); + + /** + * Return whether this token represents End Of File. + * + * @return <code>true</code>if this token represents EOF + */ + boolean isEOF(); + + /** + * Return whether this token is neither undefined, nor whitespace, nor EOF. + * + * @return <code>true</code>if this token is not undefined, not a whitespace, and not EOF + */ + boolean isOther(); + + /** + * Return a data attached to this token. The semantics of this data kept undefined by this interface. + * + * @return the data attached to this token. + */ + Object getData(); +} diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/ITokenScanner.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/ITokenScanner.java new file mode 100644 index 000000000..dd7ff43b7 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/ITokenScanner.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.jface.text.rules; + + +import org.eclipse.jface.text.IDocument; + + +/** + * A token scanner scans a range of a document and reports about the token it finds. + * A scanner has state. When asked, the scanner returns the offset and the length of the + * last found token. + * + * @see org.eclipse.jface.text.rules.IToken + * @since 2.0 + */ +public interface ITokenScanner { + + /** + * Configures the scanner by providing access to the document range that should + * be scanned. + * + * @param document the document to scan + * @param offset the offset of the document range to scan + * @param length the length of the document range to scan + */ + void setRange(IDocument document, int offset, int length); + + /** + * Returns the next token in the document. + * + * @return the next token in the document + */ + IToken nextToken(); + + /** + * Returns the offset of the last token read by this scanner. + * + * @return the offset of the last token read by this scanner + */ + int getTokenOffset(); + + /** + * Returns the length of the last token read by this scanner. + * + * @return the length of the last token read by this scanner + */ + int getTokenLength(); +} diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IWhitespaceDetector.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IWhitespaceDetector.java new file mode 100644 index 000000000..5bd84bf38 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IWhitespaceDetector.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text.rules; + + +/** + * Defines the interface by which <code>WhitespaceRule</code> + * determines whether a given character is to be considered + * whitespace in the current context. + */ +public interface IWhitespaceDetector { + + /** + * Returns whether the specified character is whitespace. + * + * @param c the character to be checked + * @return <code>true</code> if the specified character is a whitespace char + */ + boolean isWhitespace(char c); +} diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IWordDetector.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IWordDetector.java new file mode 100644 index 000000000..ae63ee80f --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/IWordDetector.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text.rules; + + +/** + * Defines the interface by which <code>WordRule</code> + * determines whether a given character is valid as part + * of a word in the current context. + */ +public interface IWordDetector { + + /** + * Returns whether the specified character is + * valid as the first character in a word. + * + * @param c the character to be checked + * @return <code>true</code> is a valid first character in a word, <code>false</code> otherwise + */ + boolean isWordStart(char c); + + /** + * Returns whether the specified character is + * valid as a subsequent character in a word. + * + * @param c the character to be checked + * @return <code>true</code> if the character is a valid word part, <code>false</code> otherwise + */ + boolean isWordPart(char c); +} diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/MultiLineRule.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/MultiLineRule.java new file mode 100644 index 000000000..7887e7842 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/MultiLineRule.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text.rules; + + +/** + * A rule for detecting patterns which begin with a given + * sequence and may end with a given sequence thereby spanning + * multiple lines. + */ +public class MultiLineRule extends PatternRule { + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specified token. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence + * @param token the token to be returned on success + */ + public MultiLineRule(String startSequence, String endSequence, IToken token) { + this(startSequence, endSequence, token, (char) 0); + } + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specific token. + * Any character which follows the given escape character will be ignored. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence + * @param token the token to be returned on success + * @param escapeCharacter the escape character + */ + public MultiLineRule(String startSequence, String endSequence, IToken token, char escapeCharacter) { + this(startSequence, endSequence, token, escapeCharacter, false); + } + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specific token. Any character that follows the + * given escape character will be ignored. <code>breakOnEOF</code> indicates whether + * EOF is equivalent to detecting the <code>endSequence</code>. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence + * @param token the token to be returned on success + * @param escapeCharacter the escape character + * @param breaksOnEOF indicates whether the end of the file terminates this rule successfully + * @since 2.1 + */ + public MultiLineRule(String startSequence, String endSequence, IToken token, char escapeCharacter, boolean breaksOnEOF) { + super(startSequence, endSequence, token, escapeCharacter, false, breaksOnEOF); + } +} diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/PatternRule.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/PatternRule.java new file mode 100644 index 000000000..d1d92f944 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/PatternRule.java @@ -0,0 +1,324 @@ +/******************************************************************************* + * Copyright (c) 2000, 2013 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Christopher Lenz (cmlenz@gmx.de) - support for line continuation + *******************************************************************************/ +package org.eclipse.jface.text.rules; + +import java.util.Arrays; +import java.util.Comparator; + +import org.eclipse.core.runtime.Assert; + + +/** + * Standard implementation of <code>IPredicateRule</code>. + * Is is capable of detecting a pattern which begins with a given start + * sequence and ends with a given end sequence. If the end sequence is + * not specified, it can be either end of line, end or file, or both. Additionally, + * the pattern can be constrained to begin in a certain column. The rule can also + * be used to check whether the text to scan covers half of the pattern, i.e. contains + * the end sequence required by the rule. + */ +public class PatternRule implements IPredicateRule { + + /** + * Comparator that orders <code>char[]</code> in decreasing array lengths. + * + * @since 3.1 + */ + private static class DecreasingCharArrayLengthComparator implements Comparator { + public int compare(Object o1, Object o2) { + return ((char[]) o2).length - ((char[]) o1).length; + } + } + + /** Internal setting for the un-initialized column constraint */ + protected static final int UNDEFINED= -1; + + /** The token to be returned on success */ + protected IToken fToken; + /** The pattern's start sequence */ + protected char[] fStartSequence; + /** The pattern's end sequence */ + protected char[] fEndSequence; + /** The pattern's column constrain */ + protected int fColumn= UNDEFINED; + /** The pattern's escape character */ + protected char fEscapeCharacter; + /** + * Indicates whether the escape character continues a line + * @since 3.0 + */ + protected boolean fEscapeContinuesLine; + /** Indicates whether end of line terminates the pattern */ + protected boolean fBreaksOnEOL; + /** Indicates whether end of file terminates the pattern */ + protected boolean fBreaksOnEOF; + + /** + * Line delimiter comparator which orders according to decreasing delimiter length. + * @since 3.1 + */ + private Comparator fLineDelimiterComparator= new DecreasingCharArrayLengthComparator(); + /** + * Cached line delimiters. + * @since 3.1 + */ + private char[][] fLineDelimiters; + /** + * Cached sorted {@linkplain #fLineDelimiters}. + * @since 3.1 + */ + private char[][] fSortedLineDelimiters; + + /** + * Creates a rule for the given starting and ending sequence. + * When these sequences are detected the rule will return the specified token. + * Alternatively, the sequence can also be ended by the end of the line. + * Any character which follows the given escapeCharacter will be ignored. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence, <code>null</code> is a legal value + * @param token the token which will be returned on success + * @param escapeCharacter any character following this one will be ignored + * @param breaksOnEOL indicates whether the end of the line also terminates the pattern + */ + public PatternRule(String startSequence, String endSequence, IToken token, char escapeCharacter, boolean breaksOnEOL) { + Assert.isTrue(startSequence != null && startSequence.length() > 0); + Assert.isTrue(endSequence != null || breaksOnEOL); + Assert.isNotNull(token); + + fStartSequence= startSequence.toCharArray(); + fEndSequence= (endSequence == null ? new char[0] : endSequence.toCharArray()); + fToken= token; + fEscapeCharacter= escapeCharacter; + fBreaksOnEOL= breaksOnEOL; + } + + /** + * Creates a rule for the given starting and ending sequence. + * When these sequences are detected the rule will return the specified token. + * Alternatively, the sequence can also be ended by the end of the line or the end of the file. + * Any character which follows the given escapeCharacter will be ignored. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence, <code>null</code> is a legal value + * @param token the token which will be returned on success + * @param escapeCharacter any character following this one will be ignored + * @param breaksOnEOL indicates whether the end of the line also terminates the pattern + * @param breaksOnEOF indicates whether the end of the file also terminates the pattern + * @since 2.1 + */ + public PatternRule(String startSequence, String endSequence, IToken token, char escapeCharacter, boolean breaksOnEOL, boolean breaksOnEOF) { + this(startSequence, endSequence, token, escapeCharacter, breaksOnEOL); + fBreaksOnEOF= breaksOnEOF; + } + + /** + * Creates a rule for the given starting and ending sequence. + * When these sequences are detected the rule will return the specified token. + * Alternatively, the sequence can also be ended by the end of the line or the end of the file. + * Any character which follows the given escapeCharacter will be ignored. An end of line + * immediately after the given <code>lineContinuationCharacter</code> will not cause the + * pattern to terminate even if <code>breakOnEOL</code> is set to true. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence, <code>null</code> is a legal value + * @param token the token which will be returned on success + * @param escapeCharacter any character following this one will be ignored + * @param breaksOnEOL indicates whether the end of the line also terminates the pattern + * @param breaksOnEOF indicates whether the end of the file also terminates the pattern + * @param escapeContinuesLine indicates whether the specified escape character is used for line + * continuation, so that an end of line immediately after the escape character does not + * terminate the pattern, even if <code>breakOnEOL</code> is set + * @since 3.0 + */ + public PatternRule(String startSequence, String endSequence, IToken token, char escapeCharacter, boolean breaksOnEOL, boolean breaksOnEOF, boolean escapeContinuesLine) { + this(startSequence, endSequence, token, escapeCharacter, breaksOnEOL, breaksOnEOF); + fEscapeContinuesLine= escapeContinuesLine; + } + + /** + * Sets a column constraint for this rule. If set, the rule's token + * will only be returned if the pattern is detected starting at the + * specified column. If the column is smaller then 0, the column + * constraint is considered removed. + * + * @param column the column in which the pattern starts + */ + public void setColumnConstraint(int column) { + if (column < 0) + column= UNDEFINED; + fColumn= column; + } + + + /** + * Evaluates this rules without considering any column constraints. + * + * @param scanner the character scanner to be used + * @return the token resulting from this evaluation + */ + protected IToken doEvaluate(ICharacterScanner scanner) { + return doEvaluate(scanner, false); + } + + /** + * Evaluates this rules without considering any column constraints. Resumes + * detection, i.e. look sonly for the end sequence required by this rule if the + * <code>resume</code> flag is set. + * + * @param scanner the character scanner to be used + * @param resume <code>true</code> if detection should be resumed, <code>false</code> otherwise + * @return the token resulting from this evaluation + * @since 2.0 + */ + protected IToken doEvaluate(ICharacterScanner scanner, boolean resume) { + + if (resume) { + + if (endSequenceDetected(scanner)) + return fToken; + + } else { + + int c= scanner.read(); + if (c == fStartSequence[0]) { + if (sequenceDetected(scanner, fStartSequence, false)) { + if (endSequenceDetected(scanner)) + return fToken; + } + } + } + + scanner.unread(); + return Token.UNDEFINED; + } + + /* + * @see IRule#evaluate(ICharacterScanner) + */ + public IToken evaluate(ICharacterScanner scanner) { + return evaluate(scanner, false); + } + + /** + * Returns whether the end sequence was detected. As the pattern can be considered + * ended by a line delimiter, the result of this method is <code>true</code> if the + * rule breaks on the end of the line, or if the EOF character is read. + * + * @param scanner the character scanner to be used + * @return <code>true</code> if the end sequence has been detected + */ + protected boolean endSequenceDetected(ICharacterScanner scanner) { + + char[][] originalDelimiters= scanner.getLegalLineDelimiters(); + int count= originalDelimiters.length; + if (fLineDelimiters == null || fLineDelimiters.length != count) { + fSortedLineDelimiters= new char[count][]; + } else { + while (count > 0 && Arrays.equals(fLineDelimiters[count - 1], originalDelimiters[count - 1])) + count--; + } + if (count != 0) { + fLineDelimiters= originalDelimiters; + System.arraycopy(fLineDelimiters, 0, fSortedLineDelimiters, 0, fLineDelimiters.length); + Arrays.sort(fSortedLineDelimiters, fLineDelimiterComparator); + } + + int readCount= 1; + int c; + while ((c= scanner.read()) != ICharacterScanner.EOF) { + if (c == fEscapeCharacter) { + // Skip escaped character(s) + if (fEscapeContinuesLine) { + c= scanner.read(); + for (int i= 0; i < fSortedLineDelimiters.length; i++) { + if (c == fSortedLineDelimiters[i][0] && sequenceDetected(scanner, fSortedLineDelimiters[i], fBreaksOnEOF)) + break; + } + } else + scanner.read(); + + } else if (fEndSequence.length > 0 && c == fEndSequence[0]) { + // Check if the specified end sequence has been found. + if (sequenceDetected(scanner, fEndSequence, fBreaksOnEOF)) + return true; + } else if (fBreaksOnEOL) { + // Check for end of line since it can be used to terminate the pattern. + for (int i= 0; i < fSortedLineDelimiters.length; i++) { + if (c == fSortedLineDelimiters[i][0] && sequenceDetected(scanner, fSortedLineDelimiters[i], fBreaksOnEOF)) + return true; + } + } + readCount++; + } + + if (fBreaksOnEOF) + return true; + + for (; readCount > 0; readCount--) + scanner.unread(); + + return false; + } + + /** + * Returns whether the next characters to be read by the character scanner + * are an exact match with the given sequence. No escape characters are allowed + * within the sequence. If specified the sequence is considered to be found + * when reading the EOF character. + * + * @param scanner the character scanner to be used + * @param sequence the sequence to be detected + * @param eofAllowed indicated whether EOF terminates the pattern + * @return <code>true</code> if the given sequence has been detected + */ + protected boolean sequenceDetected(ICharacterScanner scanner, char[] sequence, boolean eofAllowed) { + for (int i= 1; i < sequence.length; i++) { + int c= scanner.read(); + if (c == ICharacterScanner.EOF && eofAllowed) { + return true; + } else if (c != sequence[i]) { + // Non-matching character detected, rewind the scanner back to the start. + // Do not unread the first character. + scanner.unread(); + for (int j= i-1; j > 0; j--) + scanner.unread(); + return false; + } + } + + return true; + } + + /* + * @see IPredicateRule#evaluate(ICharacterScanner, boolean) + * @since 2.0 + */ + public IToken evaluate(ICharacterScanner scanner, boolean resume) { + if (fColumn == UNDEFINED) + return doEvaluate(scanner, resume); + + int c= scanner.read(); + scanner.unread(); + if (c == fStartSequence[0]) + return (fColumn == scanner.getColumn() ? doEvaluate(scanner, resume) : Token.UNDEFINED); + return Token.UNDEFINED; + } + + /* + * @see IPredicateRule#getSuccessToken() + * @since 2.0 + */ + public IToken getSuccessToken() { + return fToken; + } +} diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/RuleBasedPartitionScanner.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/RuleBasedPartitionScanner.java new file mode 100644 index 000000000..55dde65d5 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/RuleBasedPartitionScanner.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2000, 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.jface.text.rules; + + +import org.eclipse.jface.text.IDocument; + + +/** + * Scanner that exclusively uses predicate rules. + * <p> + * If a partial range is set (see {@link #setPartialRange(IDocument, int, int, String, int)} with + * content type that is not <code>null</code> then this scanner will first try the rules that match + * the given content type. + * </p> + * + * @since 2.0 + */ +public class RuleBasedPartitionScanner extends BufferedRuleBasedScanner implements IPartitionTokenScanner { + + /** The content type of the partition in which to resume scanning. */ + protected String fContentType; + /** The offset of the partition inside which to resume. */ + protected int fPartitionOffset; + + + /** + * Disallow setting the rules since this scanner + * exclusively uses predicate rules. + * + * @param rules the sequence of rules controlling this scanner + */ + public void setRules(IRule[] rules) { + throw new UnsupportedOperationException(); + } + + /* + * @see RuleBasedScanner#setRules(IRule[]) + */ + public void setPredicateRules(IPredicateRule[] rules) { + super.setRules(rules); + } + + /* + * @see ITokenScanner#setRange(IDocument, int, int) + */ + public void setRange(IDocument document, int offset, int length) { + setPartialRange(document, offset, length, null, -1); + } + + /** + * {@inheritDoc} + * <p> + * If the given content type is not <code>null</code> then this scanner will first try the rules + * that match the given content type. + * </p> + */ + public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) { + fContentType= contentType; + fPartitionOffset= partitionOffset; + if (partitionOffset > -1) { + int delta= offset - partitionOffset; + if (delta > 0) { + super.setRange(document, partitionOffset, length + delta); + fOffset= offset; + return; + } + } + super.setRange(document, offset, length); + } + + /* + * @see ITokenScanner#nextToken() + */ + public IToken nextToken() { + + + if (fContentType == null || fRules == null) { + //don't try to resume + return super.nextToken(); + } + + // inside a partition + + fColumn= UNDEFINED; + boolean resume= (fPartitionOffset > -1 && fPartitionOffset < fOffset); + fTokenOffset= resume ? fPartitionOffset : fOffset; + + IPredicateRule rule; + IToken token; + + for (int i= 0; i < fRules.length; i++) { + rule= (IPredicateRule) fRules[i]; + token= rule.getSuccessToken(); + if (fContentType.equals(token.getData())) { + token= rule.evaluate(this, resume); + if (!token.isUndefined()) { + fContentType= null; + return token; + } + } + } + + // haven't found any rule for this type of partition + fContentType= null; + if (resume) + fOffset= fPartitionOffset; + return super.nextToken(); + } +} diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/RuleBasedScanner.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/RuleBasedScanner.java new file mode 100644 index 000000000..dc2777672 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/RuleBasedScanner.java @@ -0,0 +1,216 @@ +/******************************************************************************* + * Copyright (c) 2000, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.jface.text.rules; + + +import org.eclipse.core.runtime.Assert; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; + + +/** + * A generic scanner which can be "programmed" with a sequence of rules. + * The scanner is used to get the next token by evaluating its rule in sequence until + * one is successful. If a rule returns a token which is undefined, the scanner will proceed to + * the next rule. Otherwise the token provided by the rule will be returned by + * the scanner. If no rule returned a defined token, this scanner returns a token + * which returns <code>true</code> when calling <code>isOther</code>, unless the end + * of the file is reached. In this case the token returns <code>true</code> when calling + * <code>isEOF</code>. + * + * @see IRule + */ +public class RuleBasedScanner implements ICharacterScanner, ITokenScanner { + + /** The list of rules of this scanner */ + protected IRule[] fRules; + /** The token to be returned by default if no rule fires */ + protected IToken fDefaultReturnToken; + /** The document to be scanned */ + protected IDocument fDocument; + /** The cached legal line delimiters of the document */ + protected char[][] fDelimiters; + /** The offset of the next character to be read */ + protected int fOffset; + /** The end offset of the range to be scanned */ + protected int fRangeEnd; + /** The offset of the last read token */ + protected int fTokenOffset; + /** The cached column of the current scanner position */ + protected int fColumn; + /** Internal setting for the un-initialized column cache. */ + protected static final int UNDEFINED= -1; + + /** + * Creates a new rule based scanner which does not have any rule. + */ + public RuleBasedScanner() { + } + + /** + * Configures the scanner with the given sequence of rules. + * + * @param rules the sequence of rules controlling this scanner + */ + public void setRules(IRule[] rules) { + if (rules != null) { + fRules= new IRule[rules.length]; + System.arraycopy(rules, 0, fRules, 0, rules.length); + } else + fRules= null; + } + + /** + * Configures the scanner's default return token. This is the token + * which is returned when none of the rules fired and EOF has not been + * reached. + * + * @param defaultReturnToken the default return token + * @since 2.0 + */ + public void setDefaultReturnToken(IToken defaultReturnToken) { + Assert.isNotNull(defaultReturnToken.getData()); + fDefaultReturnToken= defaultReturnToken; + } + + /* + * @see ITokenScanner#setRange(IDocument, int, int) + */ + public void setRange(final IDocument document, int offset, int length) { + Assert.isLegal(document != null); + final int documentLength= document.getLength(); + checkRange(offset, length, documentLength); + + fDocument= document; + fOffset= offset; + fColumn= UNDEFINED; + fRangeEnd= offset + length; + + String[] delimiters= fDocument.getLegalLineDelimiters(); + fDelimiters= new char[delimiters.length][]; + for (int i= 0; i < delimiters.length; i++) + fDelimiters[i]= delimiters[i].toCharArray(); + + if (fDefaultReturnToken == null) + fDefaultReturnToken= new Token(null); + } + + /** + * Checks that the given range is valid. + * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=69292 + * + * @param offset the offset of the document range to scan + * @param length the length of the document range to scan + * @param documentLength the document's length + * @since 3.3 + */ + private void checkRange(int offset, int length, int documentLength) { + Assert.isLegal(offset > -1); + Assert.isLegal(length > -1); + Assert.isLegal(offset + length <= documentLength); + } + + /* + * @see ITokenScanner#getTokenOffset() + */ + public int getTokenOffset() { + return fTokenOffset; + } + + /* + * @see ITokenScanner#getTokenLength() + */ + public int getTokenLength() { + if (fOffset < fRangeEnd) + return fOffset - getTokenOffset(); + return fRangeEnd - getTokenOffset(); + } + + + /* + * @see ICharacterScanner#getColumn() + */ + public int getColumn() { + if (fColumn == UNDEFINED) { + try { + int line= fDocument.getLineOfOffset(fOffset); + int start= fDocument.getLineOffset(line); + + fColumn= fOffset - start; + + } catch (BadLocationException ex) { + } + } + return fColumn; + } + + /* + * @see ICharacterScanner#getLegalLineDelimiters() + */ + public char[][] getLegalLineDelimiters() { + return fDelimiters; + } + + /* + * @see ITokenScanner#nextToken() + */ + public IToken nextToken() { + + fTokenOffset= fOffset; + fColumn= UNDEFINED; + + if (fRules != null) { + for (int i= 0; i < fRules.length; i++) { + IToken token= (fRules[i].evaluate(this)); + if (!token.isUndefined()) + return token; + } + } + + if (read() == EOF) + return Token.EOF; + return fDefaultReturnToken; + } + + /* + * @see ICharacterScanner#read() + */ + public int read() { + + try { + + if (fOffset < fRangeEnd) { + try { + return fDocument.getChar(fOffset); + } catch (BadLocationException e) { + } + } + + return EOF; + + } finally { + ++ fOffset; + fColumn= UNDEFINED; + } + } + + /* + * @see ICharacterScanner#unread() + */ + public void unread() { + --fOffset; + fColumn= UNDEFINED; + } +} + + diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/SingleLineRule.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/SingleLineRule.java new file mode 100644 index 000000000..5b26d852d --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/SingleLineRule.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Christopher Lenz (cmlenz@gmx.de) - support for line continuation + *******************************************************************************/ +package org.eclipse.jface.text.rules; + + +/** + * A specific configuration of pattern rule whereby + * the pattern begins with a specific sequence and may + * end with a specific sequence, but will not span more + * than a single line. + */ +public class SingleLineRule extends PatternRule { + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specified token. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence + * @param token the token to be returned on success + */ + public SingleLineRule(String startSequence, String endSequence, IToken token) { + this(startSequence, endSequence, token, (char) 0); + } + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specified token. + * Any character which follows the given escape character + * will be ignored. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence + * @param token the token to be returned on success + * @param escapeCharacter the escape character + */ + public SingleLineRule(String startSequence, String endSequence, IToken token, char escapeCharacter) { + this(startSequence, endSequence, token, escapeCharacter, false); + } + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specified token. Alternatively, the + * line can also be ended with the end of the file. + * Any character which follows the given escape character + * will be ignored. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence + * @param token the token to be returned on success + * @param escapeCharacter the escape character + * @param breaksOnEOF indicates whether the end of the file successfully terminates this rule + * @since 2.1 + */ + public SingleLineRule(String startSequence, String endSequence, IToken token, char escapeCharacter, boolean breaksOnEOF) { + super(startSequence, endSequence, token, escapeCharacter, true, breaksOnEOF); + } + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specified token. Alternatively, the + * line can also be ended with the end of the file. + * Any character which follows the given escape character + * will be ignored. In addition, an escape character immediately before an + * end of line can be set to continue the line. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence + * @param token the token to be returned on success + * @param escapeCharacter the escape character + * @param breaksOnEOF indicates whether the end of the file successfully terminates this rule + * @param escapeContinuesLine indicates whether the specified escape character is used for line + * continuation, so that an end of line immediately after the escape character does not + * terminate the line, even if <code>breakOnEOL</code> is true + * @since 3.0 + */ + public SingleLineRule(String startSequence, String endSequence, IToken token, char escapeCharacter, boolean breaksOnEOF, boolean escapeContinuesLine) { + super(startSequence, endSequence, token, escapeCharacter, true, breaksOnEOF, escapeContinuesLine); + } +} diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/Token.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/Token.java new file mode 100644 index 000000000..24f48a458 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/Token.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.jface.text.rules; + +import org.eclipse.core.runtime.Assert; + + +/** + * Standard implementation of <code>IToken</code>. + */ +public class Token implements IToken { + + /** Internal token type: Undefined */ + private static final int T_UNDEFINED= 0; + /** Internal token type: EOF */ + private static final int T_EOF= 1; + /** Internal token type: Whitespace */ + private static final int T_WHITESPACE= 2; + /** Internal token type: Others */ + private static final int T_OTHER= 3; + + + /** + * Standard token: Undefined. + */ + public static final IToken UNDEFINED= new Token(T_UNDEFINED); + /** + * Standard token: End Of File. + */ + public static final IToken EOF= new Token(T_EOF); + /** + * Standard token: Whitespace. + */ + public static final IToken WHITESPACE= new Token(T_WHITESPACE); + + /** + * Standard token: Neither {@link #UNDEFINED}, {@link #WHITESPACE}, nor {@link #EOF}. + * @deprecated will be removed + */ + public static final IToken OTHER= new Token(T_OTHER); + + /** The type of this token */ + private int fType; + /** The data associated with this token */ + private Object fData; + + /** + * Creates a new token according to the given specification which does not + * have any data attached to it. + * + * @param type the type of the token + * @since 2.0 + */ + private Token(int type) { + fType= type; + fData= null; + } + + /** + * Creates a new token which represents neither undefined, whitespace, nor EOF. + * The newly created token has the given data attached to it. + * + * @param data the data attached to the newly created token + */ + public Token(Object data) { + fType= T_OTHER; + fData= data; + } + + /** + * Re-initializes the data of this token. The token may not represent + * undefined, whitespace, or EOF. + * + * @param data to be attached to the token + * @since 2.0 + */ + public void setData(Object data) { + Assert.isTrue(isOther()); + fData= data; + } + + /* + * @see IToken#getData() + */ + public Object getData() { + return fData; + } + + /* + * @see IToken#isOther() + */ + public boolean isOther() { + return (fType == T_OTHER); + } + + /* + * @see IToken#isEOF() + */ + public boolean isEOF() { + return (fType == T_EOF); + } + + /* + * @see IToken#isWhitespace() + */ + public boolean isWhitespace() { + return (fType == T_WHITESPACE); + } + + /* + * @see IToken#isUndefined() + */ + public boolean isUndefined() { + return (fType == T_UNDEFINED); + } +} diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/WhitespaceRule.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/WhitespaceRule.java new file mode 100644 index 000000000..6bd1af7f2 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/WhitespaceRule.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2000, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Anton Leherbauer (Wind River Systems) - [misc] Allow custom token for WhitespaceRule - https://bugs.eclipse.org/bugs/show_bug.cgi?id=251224 + *******************************************************************************/ +package org.eclipse.jface.text.rules; + + +import org.eclipse.core.runtime.Assert; + + +/** + * An implementation of <code>IRule</code> capable of detecting whitespace. + * A whitespace rule uses a whitespace detector in order to find out which + * characters are whitespace characters. + * + * @see IWhitespaceDetector + */ +public class WhitespaceRule implements IRule { + + /** The whitespace detector used by this rule */ + protected IWhitespaceDetector fDetector; + + /** + * The token returned for whitespace. + * @since 3.5 + */ + protected final IToken fWhitespaceToken; + + /** + * Creates a rule which, with the help of an whitespace detector, will return + * {@link Token#WHITESPACE} when a whitespace is detected. + * + * @param detector the rule's whitespace detector + */ + public WhitespaceRule(IWhitespaceDetector detector) { + this(detector, Token.WHITESPACE); + } + + /** + * Creates a rule which, with the help of an whitespace detector, will return the given + * whitespace token when a whitespace is detected. + * + * @param detector the rule's whitespace detector + * @param token the token returned for whitespace + * @since 3.5 + */ + public WhitespaceRule(IWhitespaceDetector detector, IToken token) { + Assert.isNotNull(detector); + Assert.isNotNull(token); + fDetector= detector; + fWhitespaceToken= token; + } + + /** + * {@inheritDoc} + * + * @return {@link #fWhitespaceToken} if whitespace got detected, {@link Token#UNDEFINED} + * otherwise + */ + public IToken evaluate(ICharacterScanner scanner) { + int c= scanner.read(); + if (fDetector.isWhitespace((char) c)) { + do { + c= scanner.read(); + } while (fDetector.isWhitespace((char) c)); + scanner.unread(); + return fWhitespaceToken; + } + + scanner.unread(); + return Token.UNDEFINED; + } +} diff --git a/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/WordRule.java b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/WordRule.java new file mode 100644 index 000000000..b52a7ea38 --- /dev/null +++ b/experimental/compensator/org.eclipse.fx.text/src/org/eclipse/jface/text/rules/WordRule.java @@ -0,0 +1,174 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Doug Satchwell <doug.satchwell@ymail.com> - [implementation] Performance issue with jface text WordRule - http://bugs.eclipse.org/277299 + *******************************************************************************/ +package org.eclipse.jface.text.rules; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.Assert; + + +/** + * An implementation of {@link IRule} capable of detecting words. A word rule also allows to + * associate a token to a word. That is, not only can the rule be used to provide tokens for exact + * matches, but also for the generalized notion of a word in the context in which it is used. A word + * rule uses a word detector to determine what a word is. + * + * @see IWordDetector + */ +public class WordRule implements IRule { + + /** Internal setting for the un-initialized column constraint. */ + protected static final int UNDEFINED= -1; + + /** The word detector used by this rule. */ + protected IWordDetector fDetector; + /** The default token to be returned on success and if nothing else has been specified. */ + protected IToken fDefaultToken; + /** The column constraint. */ + protected int fColumn= UNDEFINED; + /** The table of predefined words and token for this rule. */ + protected Map fWords= new HashMap(); + /** Buffer used for pattern detection. */ + private StringBuffer fBuffer= new StringBuffer(); + /** + * Tells whether this rule is case sensitive. + * @since 3.3 + */ + private boolean fIgnoreCase= false; + + + /** + * Creates a rule which, with the help of an word detector, will return the token + * associated with the detected word. If no token has been associated, the scanner + * will be rolled back and an undefined token will be returned in order to allow + * any subsequent rules to analyze the characters. + * + * @param detector the word detector to be used by this rule, may not be <code>null</code> + * @see #addWord(String, IToken) + */ + public WordRule(IWordDetector detector) { + this(detector, Token.UNDEFINED, false); + } + + /** + * Creates a rule which, with the help of a word detector, will return the token + * associated with the detected word. If no token has been associated, the + * specified default token will be returned. + * + * @param detector the word detector to be used by this rule, may not be <code>null</code> + * @param defaultToken the default token to be returned on success + * if nothing else is specified, may not be <code>null</code> + * @see #addWord(String, IToken) + */ + public WordRule(IWordDetector detector, IToken defaultToken) { + this(detector, defaultToken, false); + } + + /** + * Creates a rule which, with the help of a word detector, will return the token + * associated with the detected word. If no token has been associated, the + * specified default token will be returned. + * + * @param detector the word detector to be used by this rule, may not be <code>null</code> + * @param defaultToken the default token to be returned on success + * if nothing else is specified, may not be <code>null</code> + * @param ignoreCase the case sensitivity associated with this rule + * @see #addWord(String, IToken) + * @since 3.3 + */ + public WordRule(IWordDetector detector, IToken defaultToken, boolean ignoreCase) { + Assert.isNotNull(detector); + Assert.isNotNull(defaultToken); + + fDetector= detector; + fDefaultToken= defaultToken; + fIgnoreCase= ignoreCase; + } + + /** + * Adds a word and the token to be returned if it is detected. + * + * @param word the word this rule will search for, may not be <code>null</code> + * @param token the token to be returned if the word has been found, may not be <code>null</code> + */ + public void addWord(String word, IToken token) { + Assert.isNotNull(word); + Assert.isNotNull(token); + + // If case-insensitive, convert to lower case before adding to the map + if (fIgnoreCase) + word= word.toLowerCase(); + fWords.put(word, token); + } + + /** + * Sets a column constraint for this rule. If set, the rule's token + * will only be returned if the pattern is detected starting at the + * specified column. If the column is smaller then 0, the column + * constraint is considered removed. + * + * @param column the column in which the pattern starts + */ + public void setColumnConstraint(int column) { + if (column < 0) + column= UNDEFINED; + fColumn= column; + } + + /* + * @see IRule#evaluate(ICharacterScanner) + */ + public IToken evaluate(ICharacterScanner scanner) { + int c= scanner.read(); + if (c != ICharacterScanner.EOF && fDetector.isWordStart((char) c)) { + if (fColumn == UNDEFINED || (fColumn == scanner.getColumn() - 1)) { + + fBuffer.setLength(0); + do { + fBuffer.append((char) c); + c= scanner.read(); + } while (c != ICharacterScanner.EOF && fDetector.isWordPart((char) c)); + scanner.unread(); + + String buffer= fBuffer.toString(); + // If case-insensitive, convert to lower case before accessing the map + if (fIgnoreCase) + buffer= buffer.toLowerCase(); + + IToken token= (IToken)fWords.get(buffer); + + if (token != null) + return token; + + if (fDefaultToken.isUndefined()) + unreadBuffer(scanner); + + return fDefaultToken; + } + } + + scanner.unread(); + return Token.UNDEFINED; + } + + /** + * Returns the characters in the buffer to the scanner. + * + * @param scanner the scanner to be used + */ + protected void unreadBuffer(ICharacterScanner scanner) { + for (int i= fBuffer.length() - 1; i >= 0; i--) + scanner.unread(); + } + +} |