├── .gitignore ├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── xtend-gradle-plugin ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── gradle-plugins │ │ │ ├── org.xtend.xtend.properties │ │ │ └── org.xtend.xtend-base.properties │ │ └── java │ │ └── org │ │ └── xtend │ │ └── gradle │ │ ├── tasks │ │ ├── XtendSourceSet.java │ │ ├── XtendEclipsePreferences.xtend │ │ ├── DefaultXtendSourceSet.xtend │ │ ├── XtendOptions.xtend │ │ ├── XtendRuntime.xtend │ │ ├── XtendEclipseSettings.xtend │ │ └── XtendCompile.xtend │ │ ├── GradleExtensions.xtend │ │ ├── XtendBasePlugin.xtend │ │ └── XtendPlugin.xtend └── build.gradle ├── .travis └── releaseOnTag.sh ├── xtend-android-gradle-plugin ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── gradle-plugins │ │ │ └── org.xtend.xtend-android.properties │ │ └── java │ │ └── org │ │ └── xtend │ │ └── gradle │ │ └── XtendAndroidPlugin.xtend └── build.gradle ├── README.md ├── .travis.yml ├── xtend-gradle-lib ├── build.gradle └── src │ └── main │ └── java │ └── org │ └── xtend │ ├── enhance │ └── batch │ │ ├── ClassFileDebugSourceExtractor.java │ │ ├── Main.java │ │ └── XtendDebugInfoInstaller.java │ └── compiler │ └── batch │ ├── Main.java │ └── LeakFreeXtendCompiler.java ├── gradlew.bat ├── gradlew └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | .settings/ 4 | .gradle/ 5 | build/ 6 | bin/ -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include 'xtend-android-gradle-plugin', 'xtend-gradle-plugin','xtend-gradle-lib' -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xtext/xtend-gradle-plugin/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /xtend-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.xtend.xtend.properties: -------------------------------------------------------------------------------- 1 | implementation-class=org.xtend.gradle.XtendPlugin -------------------------------------------------------------------------------- /xtend-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.xtend.xtend-base.properties: -------------------------------------------------------------------------------- 1 | implementation-class=org.xtend.gradle.XtendBasePlugin -------------------------------------------------------------------------------- /.travis/releaseOnTag.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ev 3 | if [ -n "${TRAVIS_TAG}" ]; then 4 | ./gradlew release "-PreleaseVersion=${TRAVIS_TAG}" 5 | fi 6 | -------------------------------------------------------------------------------- /xtend-android-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.xtend.xtend-android.properties: -------------------------------------------------------------------------------- 1 | implementation-class=org.xtend.gradle.XtendAndroidPlugin -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | The [Xtend Gradle Plugin](http://xtext.github.io/xtext-gradle-plugin/xtend.html) is now part of the new [Xtext Gradle Plugin](https://github.com/xtext/xtext-gradle-plugin). 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | sudo: false 3 | cache: 4 | directories: 5 | - $HOME/.gradle 6 | install: 7 | - true 8 | script: 9 | - ./gradlew check && ./.travis/releaseOnTag.sh 10 | -------------------------------------------------------------------------------- /xtend-android-gradle-plugin/build.gradle: -------------------------------------------------------------------------------- 1 | description = 'A Gradle Plugin that integrates Xtend into the Android build system' 2 | 3 | dependencies { 4 | compile project(':xtend-gradle-plugin') 5 | compile 'com.android.tools.build:gradle:1.5.0' 6 | } 7 | -------------------------------------------------------------------------------- /xtend-gradle-lib/build.gradle: -------------------------------------------------------------------------------- 1 | description = 'A library that provides build tooling not yet present in xtend-core' 2 | 3 | dependencies { 4 | compile ('org.eclipse.xtend:org.eclipse.xtend.core:2.5.4') { 5 | exclude group:'asm', module:'asm' 6 | } 7 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Sep 24 10:11:07 CEST 2014 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.7-bin.zip 7 | -------------------------------------------------------------------------------- /xtend-gradle-plugin/build.gradle: -------------------------------------------------------------------------------- 1 | description = 'A Gradle Plugin for building Xtend projects' 2 | 3 | dependencies { 4 | compile 'org.eclipse.core:org.eclipse.core.runtime:3.7.0' 5 | } 6 | 7 | jar { 8 | manifest { 9 | attributes("Implementation-Version": project.version) 10 | } 11 | } -------------------------------------------------------------------------------- /xtend-gradle-plugin/src/main/java/org/xtend/gradle/tasks/XtendSourceSet.java: -------------------------------------------------------------------------------- 1 | package org.xtend.gradle.tasks; 2 | 3 | import java.io.File; 4 | 5 | import groovy.lang.Closure; 6 | 7 | import org.gradle.api.file.SourceDirectorySet; 8 | 9 | public interface XtendSourceSet { 10 | SourceDirectorySet getXtend(); 11 | 12 | XtendSourceSet xtend(Closure configureClosure); 13 | 14 | File getXtendOutputDir(); 15 | 16 | void setXtendOutputDir(Object dir); 17 | } 18 | -------------------------------------------------------------------------------- /xtend-gradle-plugin/src/main/java/org/xtend/gradle/tasks/XtendEclipsePreferences.xtend: -------------------------------------------------------------------------------- 1 | package org.xtend.gradle.tasks 2 | 3 | import org.eclipse.core.internal.preferences.EclipsePreferences 4 | import org.eclipse.core.runtime.Path 5 | import org.gradle.api.Project 6 | import org.osgi.service.prefs.BackingStoreException 7 | 8 | class XtendEclipsePreferences extends EclipsePreferences { 9 | 10 | Project project 11 | 12 | new (Project project) { 13 | this.project = project 14 | } 15 | 16 | override protected getLocation() { 17 | val path = new Path(project.projectDir.absolutePath) 18 | computeLocation(path, "org.eclipse.xtend.core.Xtend") 19 | } 20 | 21 | override public save() throws BackingStoreException { 22 | super.save 23 | } 24 | 25 | override public load() throws BackingStoreException { 26 | super.load 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /xtend-gradle-lib/src/main/java/org/xtend/enhance/batch/ClassFileDebugSourceExtractor.java: -------------------------------------------------------------------------------- 1 | package org.xtend.enhance.batch; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import org.objectweb.asm.ClassReader; 7 | import org.objectweb.asm.ClassVisitor; 8 | import org.objectweb.asm.Opcodes; 9 | 10 | import com.google.common.io.Files; 11 | 12 | public class ClassFileDebugSourceExtractor { 13 | 14 | protected static class Visitor extends ClassVisitor { 15 | 16 | protected Visitor() { 17 | super(Opcodes.ASM5); 18 | } 19 | protected String source; 20 | 21 | @Override 22 | public void visitSource(String arg0, String arg1) { 23 | this.source = arg0; 24 | } 25 | } 26 | 27 | public String getDebugSourceFileName(File classFile) throws IOException { 28 | ClassReader cr = new ClassReader(Files.toByteArray(classFile)); 29 | Visitor visitor = new Visitor(); 30 | cr.accept(visitor, ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES); 31 | return visitor.source; 32 | } 33 | } -------------------------------------------------------------------------------- /xtend-gradle-plugin/src/main/java/org/xtend/gradle/tasks/DefaultXtendSourceSet.xtend: -------------------------------------------------------------------------------- 1 | package org.xtend.gradle.tasks 2 | 3 | import groovy.lang.Closure 4 | import org.gradle.api.file.SourceDirectorySet 5 | import org.gradle.api.internal.file.DefaultSourceDirectorySet 6 | import org.gradle.api.internal.file.FileResolver 7 | 8 | class DefaultXtendSourceSet implements XtendSourceSet { 9 | 10 | SourceDirectorySet srcDirs 11 | Object xtendOutputDir 12 | FileResolver fileResolver 13 | 14 | new(FileResolver fileResolver) { 15 | this.fileResolver = fileResolver 16 | this.srcDirs = new DefaultSourceDirectorySet("xtend", fileResolver) 17 | } 18 | 19 | override getXtend() { 20 | srcDirs 21 | } 22 | 23 | override getXtendOutputDir() { 24 | fileResolver.resolve(xtendOutputDir) 25 | } 26 | 27 | override setXtendOutputDir(Object dir) { 28 | this.xtendOutputDir = dir 29 | } 30 | 31 | override xtend(Closure configureClosure) { 32 | configureClosure.call(srcDirs) 33 | this 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /xtend-gradle-plugin/src/main/java/org/xtend/gradle/tasks/XtendOptions.xtend: -------------------------------------------------------------------------------- 1 | package org.xtend.gradle.tasks 2 | 3 | import org.eclipse.xtend.lib.annotations.Accessors 4 | import org.gradle.api.tasks.Input 5 | import org.gradle.api.tasks.Nested 6 | import org.gradle.api.tasks.Optional 7 | import org.gradle.api.tasks.compile.AbstractOptions 8 | 9 | @Accessors 10 | abstract class AbstractXtendOptions extends AbstractOptions { 11 | @Input boolean hideSyntheticVariables = true 12 | @Input boolean xtendAsPrimaryDebugSource = false 13 | @Input boolean addSuppressWarnings = true 14 | @Nested GeneratedAnnotationOptions generatedAnnotation = new GeneratedAnnotationOptions 15 | } 16 | 17 | @Accessors 18 | class GeneratedAnnotationOptions extends AbstractOptions { 19 | @Input boolean active 20 | @Input boolean includeDate 21 | @Input @Optional String comment 22 | } 23 | 24 | @Accessors 25 | class XtendCompileOptions extends AbstractXtendOptions { 26 | @Input String encoding = "UTF-8" 27 | } 28 | 29 | @Accessors 30 | class XtendEclipseOptions extends AbstractXtendOptions { 31 | } 32 | -------------------------------------------------------------------------------- /xtend-gradle-plugin/src/main/java/org/xtend/gradle/GradleExtensions.xtend: -------------------------------------------------------------------------------- 1 | package org.xtend.gradle 2 | 3 | import org.eclipse.xtext.xbase.lib.Procedures.Procedure1 4 | import org.gradle.api.Task 5 | import org.gradle.api.artifacts.ExternalModuleDependency 6 | import org.gradle.api.artifacts.dsl.DependencyHandler 7 | import org.gradle.api.execution.TaskExecutionAdapter 8 | import org.gradle.api.file.FileCollection 9 | 10 | class GradleExtensions { 11 | static def beforeExecute(T taskToConfigure, (T)=>void action) { 12 | taskToConfigure.project.gradle.taskGraph.addTaskExecutionListener( 13 | new TaskExecutionAdapter() { 14 | override beforeExecute(Task task) { 15 | if (task === taskToConfigure) { 16 | action.apply(task as T) 17 | } 18 | } 19 | } 20 | ) 21 | } 22 | 23 | static def externalModule(DependencyHandler dependencyHandler, String coordinates, 24 | Procedure1 config) { 25 | val dependency = dependencyHandler.create(coordinates) 26 | config.apply(dependency as ExternalModuleDependency) 27 | dependency 28 | } 29 | 30 | static def + (FileCollection first, FileCollection second) { 31 | first.plus(second) 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /xtend-gradle-plugin/src/main/java/org/xtend/gradle/XtendBasePlugin.xtend: -------------------------------------------------------------------------------- 1 | package org.xtend.gradle 2 | 3 | import org.gradle.api.Plugin 4 | import org.gradle.api.Project 5 | import org.gradle.api.artifacts.Configuration 6 | import org.gradle.api.plugins.JavaBasePlugin 7 | import org.gradle.plugins.ide.eclipse.EclipsePlugin 8 | import org.gradle.plugins.ide.eclipse.model.EclipseModel 9 | import org.xtend.gradle.tasks.XtendEclipseSettings 10 | import org.xtend.gradle.tasks.XtendRuntime 11 | 12 | class XtendBasePlugin implements Plugin { 13 | Project project 14 | Configuration xtendCompileOnlyConfiguration 15 | 16 | override apply(Project project) { 17 | this.project = project 18 | project.extensions.create("xtendRuntime", XtendRuntime, project) 19 | xtendCompileOnlyConfiguration = project.configurations.create("xtendCompileOnly") 20 | project.plugins.apply(JavaBasePlugin) //Xtend Bug 435429 21 | configureEclipsePluginIfPresent 22 | } 23 | 24 | private def configureEclipsePluginIfPresent() { 25 | project.afterEvaluate [ 26 | val eclipse = project.extensions.findByType(EclipseModel) 27 | if (eclipse !== null) { 28 | eclipse.project.buildCommand("org.eclipse.xtext.ui.shared.xtextBuilder") 29 | eclipse.project.natures("org.eclipse.xtext.ui.shared.xtextNature") 30 | eclipse.classpath.plusConfigurations += xtendCompileOnlyConfiguration 31 | val settingsTask = project.tasks.create("xtendEclipseSettings", XtendEclipseSettings) 32 | project.tasks.getAt(EclipsePlugin.ECLIPSE_TASK_NAME).dependsOn(settingsTask) 33 | } 34 | ] 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /xtend-gradle-lib/src/main/java/org/xtend/enhance/batch/Main.java: -------------------------------------------------------------------------------- 1 | package org.xtend.enhance.batch; 2 | 3 | import java.io.File; 4 | import java.util.Arrays; 5 | import java.util.Iterator; 6 | 7 | import org.eclipse.xtend.core.XtendInjectorSingleton; 8 | 9 | import com.google.inject.Injector; 10 | 11 | public class Main { 12 | 13 | public static void main(String[] args) { 14 | enhance(args); 15 | } 16 | 17 | public static boolean enhance(String[] args) { 18 | Injector injector = XtendInjectorSingleton.INJECTOR; 19 | XtendDebugInfoInstaller installer = injector.getInstance(XtendDebugInfoInstaller.class); 20 | if ((args == null) || (args.length == 0)) { 21 | printUsage(); 22 | return false; 23 | } 24 | Iterator arguments = Arrays.asList(args).iterator(); 25 | while (arguments.hasNext()) { 26 | String argument = arguments.next(); 27 | if ("-o".equals(argument.trim())) { 28 | installer.setOutputDirectory(new File(arguments.next().trim())); 29 | } else if ("-hideSynthetic".equals(argument.trim())) { 30 | installer.setHideSyntheticVariables(true); 31 | } else if ("-xtendAsPrimary".equals(argument.trim())) { 32 | installer.setXtendAsPrimaryDebugSource(true); 33 | } else if ("-c".equals(argument.trim())) { 34 | installer.setClassesDirectory(new File(arguments.next().trim())); 35 | } else { 36 | installer.getInputDirectories().add(new File(argument)); 37 | } 38 | } 39 | try { 40 | installer.installDebugInfo(); 41 | } catch (Exception e) { 42 | e.printStackTrace(System.out); 43 | return false; 44 | } 45 | return true; 46 | } 47 | 48 | private static void printUsage() { 49 | System.out.println("Usage: Main "); 50 | System.out.println("where possible options include:"); 51 | System.out.println("-d Specify the classes directory that should be enhanced"); 52 | System.out.println("-hideSynthetic Hide synthetic variables in debugger"); 53 | System.out.println("-xtendAsPrimary Install Xtend as main debug source (useful for Android)"); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /xtend-gradle-plugin/src/main/java/org/xtend/gradle/XtendPlugin.xtend: -------------------------------------------------------------------------------- 1 | package org.xtend.gradle 2 | 3 | import javax.inject.Inject 4 | import org.gradle.api.Plugin 5 | import org.gradle.api.Project 6 | import org.gradle.api.internal.file.FileResolver 7 | import org.gradle.api.internal.plugins.DslObject 8 | import org.gradle.api.plugins.JavaPlugin 9 | import org.gradle.api.plugins.JavaPluginConvention 10 | import org.gradle.api.tasks.compile.JavaCompile 11 | import org.gradle.plugins.ide.eclipse.EclipsePlugin 12 | import org.xtend.gradle.tasks.DefaultXtendSourceSet 13 | import org.xtend.gradle.tasks.XtendCompile 14 | 15 | import static extension org.xtend.gradle.GradleExtensions.* 16 | import org.xtend.gradle.tasks.XtendRuntime 17 | 18 | class XtendPlugin implements Plugin { 19 | 20 | FileResolver fileResolver 21 | 22 | @Inject 23 | new(FileResolver fileResolver) { 24 | this.fileResolver = fileResolver 25 | } 26 | 27 | override apply(Project project) { 28 | project.plugins.apply(XtendBasePlugin) 29 | project.plugins.apply(JavaPlugin) 30 | project.plugins.apply(EclipsePlugin) 31 | 32 | val xtendRuntime = project.extensions.getByType(XtendRuntime) 33 | val java = project.convention.getPlugin(JavaPluginConvention) 34 | 35 | java.sourceSets.all [ sourceSet | 36 | sourceSet.compileClasspath = sourceSet.compileClasspath + project.configurations.getAt("xtendCompileOnly") 37 | val xtendSourceSet = new DefaultXtendSourceSet(fileResolver) 38 | xtendSourceSet.xtend.source(sourceSet.java) 39 | xtendSourceSet.xtendOutputDir = '''«project.buildDir»/xtend-gen/«sourceSet.name»''' 40 | new DslObject(sourceSet).convention.plugins.put("xtend", xtendSourceSet); 41 | val compileTaskName = sourceSet.getCompileTaskName("xtend") 42 | val javaCompile = project.tasks.getAt(sourceSet.compileJavaTaskName) as JavaCompile 43 | val xtendCompile = project.tasks.create(compileTaskName, XtendCompile) [ 44 | setDescription('''Compiles the «sourceSet.name» Xtend sources''') 45 | srcDirs = xtendSourceSet.xtend 46 | project.afterEvaluate [p| 47 | classpath = sourceSet.compileClasspath 48 | destinationDir = xtendSourceSet.xtendOutputDir 49 | bootClasspath = javaCompile.options.bootClasspath 50 | classesDir = javaCompile.destinationDir 51 | sourceCompatibility = java.sourceCompatibility.toString 52 | sourceSet.java.srcDir(destinationDir) 53 | ] 54 | beforeExecute[ 55 | xtendClasspath = xtendRuntime.inferXtendClasspath(classpath) 56 | ] 57 | ] 58 | javaCompile.dependsOn(xtendCompile) 59 | javaCompile.doLast[xtendCompile.enhance] 60 | ] 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /xtend-gradle-plugin/src/main/java/org/xtend/gradle/tasks/XtendRuntime.xtend: -------------------------------------------------------------------------------- 1 | package org.xtend.gradle.tasks 2 | 3 | import java.net.URLClassLoader 4 | import java.util.regex.Pattern 5 | import org.gradle.api.GradleException 6 | import org.gradle.api.Project 7 | import org.gradle.api.file.FileCollection 8 | import org.gradle.api.invocation.Gradle 9 | 10 | import static extension org.xtend.gradle.GradleExtensions.* 11 | import java.util.concurrent.Callable 12 | 13 | class XtendRuntime { 14 | static val XTEND_LIB_PATTERN = Pattern.compile("org.eclipse.(xtend|xtext.xbase).(core|lib|lib.slim|lib.gwt)-(\\d.*?).jar") 15 | 16 | Project project 17 | 18 | new(Project project) { 19 | this.project = project 20 | } 21 | 22 | def FileCollection inferXtendClasspath(FileCollection classpath) { 23 | project.files([| 24 | for (file : classpath) { 25 | val matcher = XTEND_LIB_PATTERN.matcher(file.name) 26 | if (matcher.matches) { 27 | val xtendVersion = matcher.group(3) 28 | val dependencies = #[ 29 | project.dependencies.externalModule( 30 | '''org.eclipse.xtend:org.eclipse.xtend.core:«xtendVersion»''') [ 31 | force = true 32 | exclude(#{'group' -> 'asm'}) 33 | ], 34 | project.dependencies.externalModule('''org.xtend:xtend-gradle-lib:«pluginVersion»''') [ 35 | force = true 36 | ], 37 | project.dependencies.externalModule('com.google.inject:guice:4.0-beta4')[] 38 | ] 39 | return project.configurations.detachedConfiguration(dependencies) 40 | } 41 | } 42 | throw new GradleException( 43 | '''Could not infer Xtend classpath, because no Xtend jar was found on the «classpath» classpath''') 44 | ] as Callable) 45 | .builtBy(classpath.buildDependencies) 46 | } 47 | 48 | private def getPluginVersion() { 49 | this.class.package.implementationVersion 50 | } 51 | 52 | private static val currentCompilerClassLoader = new ThreadLocal() { 53 | override protected initialValue() { 54 | null 55 | } 56 | } 57 | 58 | static package def ClassLoader getCompilerClassLoader(FileCollection classpath) { 59 | val classPathWithoutLog4j = classpath.filter[!name.contains("log4j")] 60 | val urls = classPathWithoutLog4j.map[absoluteFile.toURI.toURL].toList 61 | val currentClassLoader = currentCompilerClassLoader.get 62 | if (currentClassLoader !== null && currentClassLoader.URLs.toList == urls) { 63 | return currentClassLoader 64 | } else { 65 | val newClassLoader = new URLClassLoader(urls, Gradle.classLoader) 66 | currentCompilerClassLoader.set(newClassLoader) 67 | return newClassLoader 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /xtend-gradle-plugin/src/main/java/org/xtend/gradle/tasks/XtendEclipseSettings.xtend: -------------------------------------------------------------------------------- 1 | package org.xtend.gradle.tasks 2 | 3 | import com.google.common.base.CharMatcher 4 | import java.io.File 5 | import org.eclipse.xtend.lib.annotations.Accessors 6 | import org.gradle.api.DefaultTask 7 | import org.gradle.api.internal.plugins.DslObject 8 | import org.gradle.api.plugins.JavaPluginConvention 9 | import org.gradle.api.tasks.Nested 10 | import org.gradle.api.tasks.TaskAction 11 | import org.gradle.api.tasks.Input 12 | import org.gradle.api.tasks.Optional 13 | 14 | @Accessors 15 | class XtendEclipseSettings extends DefaultTask { 16 | @Input @Optional String sourceCompatibility; 17 | @Nested XtendEclipseOptions options = new XtendEclipseOptions 18 | 19 | @TaskAction 20 | def writeSettings() { 21 | val settings = new XtendEclipsePreferences(project) 22 | settings.load 23 | settings.putBoolean("is_project_specific", true) 24 | settings.putBoolean("BuilderConfiguration.is_project_specific", true) 25 | settings.putBoolean("hideLocalSyntheticVariables".key, getOptions.hideSyntheticVariables) 26 | settings.putBoolean("installDslAsPrimarySource".key, getOptions.xtendAsPrimaryDebugSource) 27 | settings.putBoolean("userOutputPerSourceFolder".key, true) 28 | if (getSourceCompatibility != null) { 29 | settings.put("targetJavaVersion".key, getSourceCompatibility) 30 | } 31 | settings.putBoolean("generateSuppressWarnings".key, getOptions.addSuppressWarnings) 32 | getOptions.generatedAnnotation => [ 33 | settings.putBoolean("generateGeneratedAnnotation".key, isActive) 34 | settings.putBoolean("includeDateInGenerated".key, includeDate) 35 | settings.put("generatedAnnotationComment".key, comment ?: "") 36 | ] 37 | val java = project.convention.getPlugin(JavaPluginConvention) 38 | java.sourceSets.all [ sourceSet | 39 | val xtendSourceSet = new DslObject(sourceSet).convention.plugins.get("xtend") as XtendSourceSet 40 | xtendSourceSet.xtend.srcDirs.forEach [ 41 | settings.put(projectRelativePath.outputForSourceFolderKey, 42 | xtendSourceSet.xtendOutputDir.projectRelativePath) 43 | ] 44 | ] 45 | settings.save 46 | } 47 | 48 | private def projectRelativePath(File file) { 49 | project.projectDir.toURI.relativize(file.toURI).path.trimTrailingSeparator 50 | } 51 | 52 | private def trimTrailingSeparator(String path) { 53 | CharMatcher.anyOf("/\\").trimTrailingFrom(path) 54 | } 55 | 56 | private def String getKey(String preferenceName) { 57 | return "outlet" + "." + "DEFAULT_OUTPUT" + "." + preferenceName; 58 | } 59 | 60 | private def String getOutputForSourceFolderKey(String sourceFolder) { 61 | return getKey("sourceFolder" + "." + sourceFolder + "." + "directory"); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /xtend-android-gradle-plugin/src/main/java/org/xtend/gradle/XtendAndroidPlugin.xtend: -------------------------------------------------------------------------------- 1 | package org.xtend.gradle 2 | 3 | import com.android.build.gradle.AppExtension 4 | import com.android.build.gradle.BaseExtension 5 | import com.android.build.gradle.LibraryExtension 6 | import java.io.File 7 | import javax.inject.Inject 8 | import org.gradle.api.GradleException 9 | import org.gradle.api.Plugin 10 | import org.gradle.api.Project 11 | import org.gradle.api.internal.file.FileResolver 12 | import org.xtend.gradle.tasks.DefaultXtendSourceSet 13 | import org.xtend.gradle.tasks.XtendCompile 14 | 15 | import static extension org.xtend.gradle.GradleExtensions.* 16 | import org.xtend.gradle.tasks.XtendRuntime 17 | 18 | class XtendAndroidPlugin implements Plugin { 19 | 20 | FileResolver fileResolver 21 | 22 | @Inject 23 | new(FileResolver fileResolver) { 24 | this.fileResolver = fileResolver 25 | } 26 | 27 | override apply(Project project) { 28 | project.plugins.apply(XtendBasePlugin) 29 | val xtend = project.extensions.getByType(XtendRuntime) 30 | project.afterEvaluate [ 31 | val android = project.extensions.getByName("android") as BaseExtension 32 | val variants = if (android instanceof AppExtension) { 33 | android.applicationVariants 34 | } else if (android instanceof LibraryExtension) { 35 | android.libraryVariants 36 | } else { 37 | throw new GradleException('''Unknown packaging type «android.class.simpleName»''') 38 | } 39 | variants.all [ variant | 40 | val compileTaskName = '''compile«variant.name.toFirstUpper»Xtend''' 41 | val xtendSources = new DefaultXtendSourceSet(fileResolver) 42 | val sourceDirs = newArrayList 43 | val javaDirs = variant.sourceSets.map[javaDirectories].flatten.filter[directory] 44 | sourceDirs += javaDirs 45 | sourceDirs += #[ 46 | variant.aidlCompile.sourceOutputDir, 47 | variant.generateBuildConfig.sourceOutputDir, 48 | variant.renderscriptCompile.sourceOutputDir 49 | ] 50 | sourceDirs += variant.outputs.map[processResources.sourceOutputDir] 51 | xtendSources.xtend.srcDirs = sourceDirs 52 | xtendSources.xtendOutputDir = '''«project.buildDir»/generated/source/xtend/«variant.name»''' 53 | val xtendCompile = project.tasks.create(compileTaskName, XtendCompile) 54 | xtendCompile.srcDirs = xtendSources.xtend 55 | xtendCompile.classpath = variant.javaCompile.classpath + project.configurations.getAt("xtendCompileOnly") 56 | xtendCompile.destinationDir = xtendSources.xtendOutputDir 57 | xtendCompile.bootClasspath = android.bootClasspath.join(File.pathSeparator) 58 | xtendCompile.classpath = xtendCompile.classpath + project.files(android.bootClasspath) 59 | xtendCompile.classesDir = variant.javaCompile.destinationDir 60 | xtendCompile.options.xtendAsPrimaryDebugSource = true 61 | xtendCompile.sourceCompatibility = variant.javaCompile.sourceCompatibility 62 | xtendCompile.beforeExecute [ 63 | variant.javaCompile.classpath = variant.javaCompile.classpath + project.configurations.getAt("xtendCompileOnly") 64 | xtendClasspath = xtend.inferXtendClasspath(classpath) 65 | ] 66 | xtendCompile.setDescription('''Compiles the «variant.name» Xtend sources''') 67 | variant.registerJavaGeneratingTask(xtendCompile, xtendCompile.destinationDir) 68 | xtendCompile.dependsOn(variant.aidlCompile, variant.renderscriptCompile, variant.generateBuildConfig) 69 | xtendCompile.dependsOn(variant.outputs.map[processResources]) 70 | variant.javaCompile.doLast[xtendCompile.enhance] 71 | ] 72 | ] 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /xtend-gradle-plugin/src/main/java/org/xtend/gradle/tasks/XtendCompile.xtend: -------------------------------------------------------------------------------- 1 | package org.xtend.gradle.tasks 2 | 3 | import java.io.File 4 | import java.util.List 5 | import org.eclipse.xtend.lib.annotations.Accessors 6 | import org.gradle.api.GradleException 7 | import org.gradle.api.file.FileCollection 8 | import org.gradle.api.file.SourceDirectorySet 9 | import org.gradle.api.tasks.Input 10 | import org.gradle.api.tasks.InputFiles 11 | import org.gradle.api.tasks.Nested 12 | import org.gradle.api.tasks.Optional 13 | import org.gradle.api.tasks.SkipWhenEmpty 14 | import org.gradle.api.tasks.TaskAction 15 | import org.gradle.api.tasks.compile.AbstractCompile 16 | 17 | @Accessors 18 | class XtendCompile extends AbstractCompile { 19 | @InputFiles SourceDirectorySet srcDirs 20 | @InputFiles @Optional String bootClasspath 21 | @InputFiles FileCollection xtendClasspath 22 | @Input File classesDir; 23 | @Nested XtendCompileOptions options = new XtendCompileOptions 24 | 25 | @InputFiles @SkipWhenEmpty 26 | def getXtendSources() { 27 | project.files(getSrcDirs).asFileTree.filter[path.endsWith(".xtend")] 28 | } 29 | 30 | def getSrcDirs() { 31 | srcDirs.srcDirs.filter[dir| dir != destinationDir].filter[isDirectory] 32 | } 33 | 34 | @TaskAction 35 | override compile() { 36 | val sourcePath = getSrcDirs.map[absolutePath].join(File.pathSeparator) 37 | val compilerArguments = newArrayList( 38 | "-cp", 39 | classpath.filter[exists].asPath, 40 | "-d", 41 | project.file(destinationDir).absolutePath, 42 | "-encoding", 43 | getOptions.encoding, 44 | "-td", 45 | new File(project.buildDir, "xtend-temp").absolutePath 46 | ) 47 | if (getBootClasspath !== null) { 48 | compilerArguments += #[ 49 | "-bootClasspath", 50 | getBootClasspath 51 | ] 52 | } 53 | compilerArguments += #["-javaSourceVersion", sourceCompatibility] 54 | if (!getOptions.addSuppressWarnings) { 55 | compilerArguments += #["-noSuppressWarningsAnnotation"] 56 | } 57 | getOptions.generatedAnnotation => [ 58 | if (active) { 59 | compilerArguments += #["-generateGeneratedAnnotation"] 60 | if (includeDate) { 61 | compilerArguments += #["-includeDateInGeneratedAnnnotation"] 62 | } 63 | if (comment != null) { 64 | compilerArguments += #["-generateAnnotationComment", comment] 65 | } 66 | } 67 | ] 68 | compilerArguments.add(sourcePath) 69 | invoke("org.xtend.compiler.batch.Main", "compile", compilerArguments) 70 | } 71 | 72 | def enhance() { 73 | val enhanceArguments = newArrayList( 74 | "-c", 75 | getClassesDir.absolutePath, 76 | "-o", 77 | destinationDir.absolutePath 78 | ) 79 | 80 | if (getOptions.hideSyntheticVariables) { 81 | enhanceArguments += #["-hideSynthetic"] 82 | } 83 | if (getOptions.xtendAsPrimaryDebugSource) { 84 | enhanceArguments += #["-xtendAsPrimary"] 85 | } 86 | enhanceArguments += getSrcDirs.map[path] 87 | invoke("org.xtend.enhance.batch.Main", "enhance", enhanceArguments) 88 | } 89 | 90 | private def invoke(String className, String methodName, List arguments) { 91 | System.setProperty("org.eclipse.emf.common.util.ReferenceClearingQueue", "false") 92 | val contextClassLoader = Thread.currentThread.contextClassLoader 93 | val classLoader = XtendRuntime.getCompilerClassLoader(getXtendClasspath) 94 | try { 95 | Thread.currentThread.contextClassLoader = classLoader 96 | val main = classLoader.loadClass(className) 97 | val method = main.getMethod(methodName, typeof(String[])) 98 | val success = method.invoke(null, #[arguments as String[]]) as Boolean 99 | if (!success) { 100 | throw new GradleException('''Xtend «methodName» failed'''); 101 | } 102 | } finally { 103 | Thread.currentThread.contextClassLoader = contextClassLoader 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /xtend-gradle-lib/src/main/java/org/xtend/compiler/batch/Main.java: -------------------------------------------------------------------------------- 1 | package org.xtend.compiler.batch; 2 | 3 | import java.io.File; 4 | import java.lang.reflect.InvocationTargetException; 5 | import java.lang.reflect.Method; 6 | import java.util.Arrays; 7 | import java.util.Iterator; 8 | import java.util.List; 9 | 10 | import org.eclipse.xtend.core.XtendInjectorSingleton; 11 | import org.eclipse.xtend.core.compiler.batch.XtendBatchCompiler; 12 | import org.eclipse.xtext.util.Strings; 13 | 14 | import com.google.common.base.Joiner; 15 | import com.google.common.base.Throwables; 16 | import com.google.common.collect.Lists; 17 | import com.google.inject.Injector; 18 | 19 | public class Main { 20 | 21 | public static void main(String[] args) { 22 | if ((args == null) || (args.length == 0)) { 23 | printUsage(); 24 | return; 25 | } 26 | if (!compile(args)) { 27 | System.exit(1); 28 | } 29 | } 30 | 31 | public static boolean compile(String[] args) { 32 | Injector injector = XtendInjectorSingleton.INJECTOR; 33 | XtendBatchCompiler compiler = injector.getInstance(LeakFreeXtendCompiler.class); 34 | Iterator arguments = Arrays.asList(args).iterator(); 35 | List sourcePath = Lists.newArrayList(); 36 | while (arguments.hasNext()) { 37 | String argument = arguments.next(); 38 | if ("-d".equals(argument.trim())) { 39 | compiler.setOutputPath(arguments.next().trim()); 40 | } else if ("-classpath".equals(argument.trim()) || "-cp".equals(argument.trim())) { 41 | compiler.setClassPath(arguments.next().trim()); 42 | } else if ("-bootClasspath".equals(argument.trim())) { 43 | setOption(compiler, "bootClassPath", arguments.next().trim()); 44 | } else if ("-tempdir".equals(argument.trim()) || "-td".equals(argument.trim())) { 45 | compiler.setTempDirectory(arguments.next().trim()); 46 | } else if ("-encoding".equals(argument.trim())) { 47 | compiler.setFileEncoding(arguments.next().trim()); 48 | } else if ("-javaSourceVersion".equals(argument)) { 49 | setOption(compiler, "javaSourceVersion", arguments.next().trim()); 50 | } else if ("-noSuppressWarningsAnnotation".equals(argument)) { 51 | setOption(compiler, "generateSyntheticSuppressWarnings", false); 52 | } else if ("-generateGeneratedAnnotation".equals(argument)) { 53 | setOption(compiler, "generateGeneratedAnnotation", true); 54 | } else if ("-includeDateInGeneratedAnnnotation".equals(argument)) { 55 | setOption(compiler, "includeDateInGeneratedAnnotation", true); 56 | } else if ("-generateAnnotationComment".equals(argument)) { 57 | setOption(compiler, "generatedAnnotationComment", arguments.next().trim()); 58 | }else if ("-useCurrentClassLoader".equals(argument.trim())) { 59 | compiler.setUseCurrentClassLoaderAsParent(true); 60 | } else { 61 | sourcePath.add(argument); 62 | } 63 | } 64 | compiler.setSourcePath(Joiner.on(File.pathSeparator).join(sourcePath)); 65 | return compiler.compile(); 66 | } 67 | 68 | private static void setOption(XtendBatchCompiler compiler, String name, Object value) { 69 | try { 70 | Method setter = XtendBatchCompiler.class.getMethod("set" + Strings.toFirstUpper(name), value.getClass()); 71 | setter.invoke(compiler, value); 72 | } catch (NoSuchMethodException e) { 73 | System.err.println("the - " + name + " option is not supported by this Xtend version"); 74 | } catch (IllegalAccessException e) { 75 | Throwables.propagate(e); 76 | } catch (InvocationTargetException e) { 77 | Throwables.propagate(e.getCause()); 78 | } 79 | } 80 | 81 | private static void printUsage() { 82 | System.out.println("Usage: Main "); 83 | System.out.println("where possible options include:"); 84 | System.out.println("-d Specify where to place generated xtend files"); 85 | System.out.println("-tp Temp directory to hold generated stubs and classes"); 86 | System.out.println("-cp Specify where to find user class files"); 87 | System.out.println("-encoding Specify character encoding used by source files"); 88 | System.out.println("-useCurrentClassLoader Use current classloader as parent classloader"); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /xtend-gradle-lib/src/main/java/org/xtend/compiler/batch/LeakFreeXtendCompiler.java: -------------------------------------------------------------------------------- 1 | package org.xtend.compiler.batch; 2 | 3 | import java.io.Closeable; 4 | import java.io.File; 5 | import java.io.IOException; 6 | import java.lang.reflect.Field; 7 | import java.net.URLClassLoader; 8 | import java.util.ArrayList; 9 | import java.util.Arrays; 10 | import java.util.ConcurrentModificationException; 11 | import java.util.HashMap; 12 | import java.util.Iterator; 13 | import java.util.List; 14 | import java.util.Map; 15 | import java.util.zip.ZipFile; 16 | 17 | import org.apache.log4j.Logger; 18 | import org.eclipse.xtend.core.compiler.batch.XtendBatchCompiler; 19 | 20 | public class LeakFreeXtendCompiler extends XtendBatchCompiler { 21 | private static Logger logger = Logger.getLogger(XtendBatchCompiler.class); 22 | 23 | protected void destroyClassLoader(ClassLoader loader) { 24 | if (loader instanceof Closeable) { 25 | try { 26 | ((Closeable) loader).close(); 27 | } catch (IOException e) { 28 | logger.warn("Could not close a classloader", e); 29 | } 30 | } 31 | if (loader instanceof URLClassLoader) { 32 | clearSunJarFileFactoryCache((URLClassLoader) loader, 5); 33 | } 34 | } 35 | 36 | // Copied from OpenEJB 37 | private void clearSunJarFileFactoryCache(URLClassLoader classLoader, int attempt) { 38 | logger.debug("Clearing Sun JarFileFactory cache"); 39 | 40 | try { 41 | Class jarFileFactory = Class.forName("sun.net.www.protocol.jar.JarFileFactory"); 42 | 43 | // Do not generify these maps as their contents are NOT stable 44 | // across runtimes. 45 | Field fileCacheField = jarFileFactory.getDeclaredField("fileCache"); 46 | fileCacheField.setAccessible(true); 47 | Map fileCache = (Map) fileCacheField.get(null); 48 | Map fileCacheCopy = new HashMap(fileCache); 49 | 50 | Field urlCacheField = jarFileFactory.getDeclaredField("urlCache"); 51 | urlCacheField.setAccessible(true); 52 | Map urlCache = (Map) urlCacheField.get(null); 53 | Map urlCacheCopy = new HashMap(urlCache); 54 | 55 | // The only stable item we have here is the JarFile/ZipFile in this 56 | // map 57 | Iterator iterator = urlCacheCopy.entrySet().iterator(); 58 | List urlCacheRemoveKeys = new ArrayList(); 59 | 60 | while (iterator.hasNext()) { 61 | Map.Entry entry = (Map.Entry) iterator.next(); 62 | Object key = entry.getKey(); 63 | 64 | if (key instanceof ZipFile) { 65 | ZipFile zf = (ZipFile) key; 66 | File file = new File(zf.getName()); // getName returns 67 | // File.getPath() 68 | if (Arrays.asList(classLoader.getURLs()).contains( 69 | file.toURL())) { 70 | // Flag for removal 71 | urlCacheRemoveKeys.add(key); 72 | } 73 | } else { 74 | logger.warn("Unexpected key type: " + key); 75 | } 76 | } 77 | 78 | iterator = fileCacheCopy.entrySet().iterator(); 79 | List fileCacheRemoveKeys = new ArrayList(); 80 | 81 | while (iterator.hasNext()) { 82 | Map.Entry entry = (Map.Entry) iterator.next(); 83 | Object value = entry.getValue(); 84 | 85 | if (urlCacheRemoveKeys.contains(value)) { 86 | fileCacheRemoveKeys.add(entry.getKey()); 87 | } 88 | } 89 | 90 | // Use these unstable values as the keys for the fileCache values. 91 | iterator = fileCacheRemoveKeys.iterator(); 92 | while (iterator.hasNext()) { 93 | 94 | Object next = iterator.next(); 95 | 96 | try { 97 | Object remove = fileCache.remove(next); 98 | if (null != remove) { 99 | logger.debug("Removed item from fileCache: " + remove); 100 | } 101 | } catch (Throwable e) { 102 | logger.warn("Failed to remove item from fileCache: " + next); 103 | } 104 | } 105 | 106 | iterator = urlCacheRemoveKeys.iterator(); 107 | while (iterator.hasNext()) { 108 | 109 | Object next = iterator.next(); 110 | 111 | try { 112 | Object remove = urlCache.remove(next); 113 | 114 | try { 115 | ((ZipFile) next).close(); 116 | } catch (Throwable e) { 117 | // Ignore 118 | } 119 | 120 | if (null != remove) { 121 | logger.debug("Removed item from urlCache: " + remove); 122 | } 123 | } catch (Throwable e) { 124 | logger.warn("Failed to remove item from urlCache: " + next); 125 | } 126 | 127 | } 128 | 129 | } catch (ConcurrentModificationException e) { 130 | if (attempt > 0) { 131 | clearSunJarFileFactoryCache(classLoader, attempt - 1); 132 | } else { 133 | logger.error("Unable to clear Sun JarFileFactory cache", e); 134 | } 135 | } catch (ClassNotFoundException e) { 136 | // not a sun vm 137 | } catch (NoSuchFieldException e) { 138 | // not a sun vm 139 | } catch (Throwable e) { 140 | logger.error("Unable to clear Sun JarFileFactory cache", e); 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /xtend-gradle-lib/src/main/java/org/xtend/enhance/batch/XtendDebugInfoInstaller.java: -------------------------------------------------------------------------------- 1 | package org.xtend.enhance.batch; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileNotFoundException; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.util.Collection; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.Set; 12 | 13 | import org.apache.log4j.Logger; 14 | import org.eclipse.xtext.generator.trace.AbstractTraceRegion; 15 | import org.eclipse.xtext.generator.trace.ITraceToBytecodeInstaller; 16 | import org.eclipse.xtext.generator.trace.TraceAsPrimarySourceInstaller; 17 | import org.eclipse.xtext.generator.trace.TraceAsSmapInstaller; 18 | import org.eclipse.xtext.generator.trace.TraceFileNameProvider; 19 | import org.eclipse.xtext.generator.trace.TraceRegionSerializer; 20 | import org.eclipse.xtext.util.Strings; 21 | 22 | import com.google.common.collect.LinkedHashMultimap; 23 | import com.google.common.collect.Lists; 24 | import com.google.common.collect.Maps; 25 | import com.google.common.collect.Multimap; 26 | import com.google.common.collect.Sets; 27 | import com.google.common.io.Files; 28 | import com.google.inject.Inject; 29 | import com.google.inject.Provider; 30 | 31 | public class XtendDebugInfoInstaller { 32 | 33 | @Inject 34 | private ClassFileDebugSourceExtractor classFileDebugSourceExtractor; 35 | 36 | @Inject 37 | private Provider traceAsPrimarySourceInstallerProvider; 38 | 39 | @Inject 40 | private Provider traceAsSmapInstaller; 41 | 42 | @Inject 43 | private TraceFileNameProvider traceFileNameProvider; 44 | 45 | @Inject 46 | private TraceRegionSerializer traceRegionSerializer; 47 | 48 | private List inputDirectories = Lists.newArrayList(); 49 | private File outputDirectory; 50 | private File classesDirectory; 51 | private boolean hideSyntheticVariables; 52 | private boolean xtendAsPrimaryDebugSource; 53 | 54 | public List getInputDirectories() { 55 | return inputDirectories; 56 | } 57 | 58 | public File getClassesDirectory() { 59 | return classesDirectory; 60 | } 61 | 62 | public void setClassesDirectory(File classesDirectory) { 63 | this.classesDirectory = classesDirectory; 64 | } 65 | 66 | public File getOutputDirectory() { 67 | return outputDirectory; 68 | } 69 | 70 | public void setOutputDirectory(File outputDirectory) { 71 | this.outputDirectory = outputDirectory; 72 | } 73 | 74 | public boolean isHideSyntheticVariables() { 75 | return hideSyntheticVariables; 76 | } 77 | 78 | public void setHideSyntheticVariables(boolean hideSyntheticVariables) { 79 | this.hideSyntheticVariables = hideSyntheticVariables; 80 | } 81 | 82 | public boolean isXtendAsPrimaryDebugSource() { 83 | return xtendAsPrimaryDebugSource; 84 | } 85 | 86 | public void setXtendAsPrimaryDebugSource(boolean xtendAsPrimaryDebugSource) { 87 | this.xtendAsPrimaryDebugSource = xtendAsPrimaryDebugSource; 88 | } 89 | 90 | public void installDebugInfo() { 91 | Multimap trace2class = createTraceToClassFileMap(inputDirectories, classesDirectory); 92 | logStatus(classesDirectory, trace2class); 93 | installTraces(trace2class); 94 | } 95 | 96 | private void collectJavaSourceFile2traceFile(File root, String subdir, Map javaSourceFile2traceFile) { 97 | File file = new File(root + "/" + subdir); 98 | File[] listFiles = file.listFiles(); 99 | if (listFiles == null) { 100 | getLogger().warn("Directory " + file.getPath() + " is empty. Can't process."); 101 | return; 102 | } 103 | for (File child : listFiles) { 104 | String name = child.getName(); 105 | if (child.isDirectory()) 106 | collectJavaSourceFile2traceFile(root, subdir + "/" + name, javaSourceFile2traceFile); 107 | else if (name.endsWith(TraceFileNameProvider.TRACE_FILE_EXTENSION)) { 108 | String javaSourceFile = subdir + "/" + traceFileNameProvider.getJavaFromTrace(name); 109 | javaSourceFile2traceFile.put(javaSourceFile, child); 110 | } 111 | } 112 | } 113 | 114 | private ITraceToBytecodeInstaller createTraceToBytecodeInstaller() { 115 | if (xtendAsPrimaryDebugSource) { 116 | TraceAsPrimarySourceInstaller installer = traceAsPrimarySourceInstallerProvider.get(); 117 | installer.setHideSyntheticVariables(hideSyntheticVariables); 118 | return installer; 119 | } else { 120 | TraceAsSmapInstaller installer = traceAsSmapInstaller.get(); 121 | return installer; 122 | } 123 | } 124 | 125 | private Multimap createTraceToClassFileMap(Collection sourceFolders, File outputFolder) { 126 | Map javaSourceFile2traceFile = Maps.newLinkedHashMap(); 127 | 128 | for (File sourceRoot : sourceFolders) 129 | collectJavaSourceFile2traceFile(sourceRoot, "", javaSourceFile2traceFile); 130 | 131 | Set packageDirs = Sets.newLinkedHashSet(); 132 | for (String javaSourceFile : javaSourceFile2traceFile.keySet()) 133 | packageDirs.add(Strings.skipLastToken(javaSourceFile, "/")); 134 | 135 | Multimap trace2class = LinkedHashMultimap.create(); 136 | 137 | for (String packageDirName : packageDirs) { 138 | File packageDir = new File(outputFolder + "/" + packageDirName); 139 | if (packageDir.isDirectory()) { 140 | for (File classFile : packageDir.listFiles()) 141 | if (classFile.getName().endsWith(".class")) 142 | try { 143 | String sourceFileName = classFileDebugSourceExtractor.getDebugSourceFileName(classFile); 144 | if (Strings.isEmpty(sourceFileName)) 145 | continue; 146 | if (!sourceFileName.toLowerCase().endsWith(".java")) 147 | continue; 148 | File traceFile = javaSourceFile2traceFile.get(packageDirName + "/" + sourceFileName); 149 | if (traceFile != null) 150 | trace2class.put(traceFile, classFile); 151 | } catch (IOException e) { 152 | getLogger().error("Error reading " + classFile, e); 153 | } 154 | } 155 | } 156 | return trace2class; 157 | } 158 | 159 | private void installTrace(File traceFile, Collection classFiles) throws FileNotFoundException, IOException { 160 | ITraceToBytecodeInstaller traceToBytecodeInstaller = createTraceToBytecodeInstaller(); 161 | InputStream in = new FileInputStream(traceFile); 162 | try { 163 | AbstractTraceRegion traceRegion = traceRegionSerializer.readTraceRegionFrom(in); 164 | traceToBytecodeInstaller.setTrace(traceFileNameProvider.getJavaFromTrace(traceFile.getName()), traceRegion); 165 | if (getLogger().isDebugEnabled()) 166 | getLogger().debug("Installing trace " + traceFile + " into:"); 167 | for (File classFile : classFiles) { 168 | if (getLogger().isDebugEnabled()) 169 | getLogger().debug(" " + classFile); 170 | File outputFile = new File(classFile.getAbsolutePath().replace(classesDirectory.getAbsolutePath(), outputDirectory.getAbsolutePath())); 171 | outputFile.getParentFile().mkdirs(); 172 | Files.write(traceToBytecodeInstaller.installTrace(Files.toByteArray(classFile)), outputFile); 173 | } 174 | } finally { 175 | in.close(); 176 | } 177 | } 178 | 179 | private void installTraces(Multimap trace2class) { 180 | for (Map.Entry> e : trace2class.asMap().entrySet()) { 181 | try { 182 | installTrace(e.getKey(), e.getValue()); 183 | } catch (Exception e1) { 184 | getLogger().error(e1); 185 | } 186 | } 187 | } 188 | 189 | private void logStatus(File folder, Multimap trace2class) { 190 | String p = xtendAsPrimaryDebugSource ? "primary" : "secondary (via SMAP)"; 191 | int n = trace2class.size(); 192 | getLogger().info("Installing Xtend files into " + n + " class files as " + p + " debug sources in: " + folder); 193 | getLogger().debug("xtendAsPrimaryDebugSource=" + xtendAsPrimaryDebugSource); 194 | getLogger().debug("hideSyntheticVariables=" + hideSyntheticVariables); 195 | } 196 | 197 | private Logger getLogger() { 198 | return Logger.getLogger(getClass()); 199 | } 200 | 201 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Eclipse Public License - v 1.0 2 | 3 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC 4 | LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM 5 | CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 6 | 7 | 1. DEFINITIONS 8 | 9 | "Contribution" means: 10 | 11 | a) in the case of the initial Contributor, the initial code and documentation 12 | distributed under this Agreement, and 13 | b) in the case of each subsequent Contributor: 14 | i) changes to the Program, and 15 | ii) additions to the Program; 16 | 17 | where such changes and/or additions to the Program originate from and are 18 | distributed by that particular Contributor. A Contribution 'originates' 19 | from a Contributor if it was added to the Program by such Contributor 20 | itself or anyone acting on such Contributor's behalf. Contributions do not 21 | include additions to the Program which: (i) are separate modules of 22 | software distributed in conjunction with the Program under their own 23 | license agreement, and (ii) are not derivative works of the Program. 24 | 25 | "Contributor" means any person or entity that distributes the Program. 26 | 27 | "Licensed Patents" mean patent claims licensable by a Contributor which are 28 | necessarily infringed by the use or sale of its Contribution alone or when 29 | combined with the Program. 30 | 31 | "Program" means the Contributions distributed in accordance with this 32 | Agreement. 33 | 34 | "Recipient" means anyone who receives the Program under this Agreement, 35 | including all Contributors. 36 | 37 | 2. GRANT OF RIGHTS 38 | a) Subject to the terms of this Agreement, each Contributor hereby grants 39 | Recipient a non-exclusive, worldwide, royalty-free copyright license to 40 | reproduce, prepare derivative works of, publicly display, publicly 41 | perform, distribute and sublicense the Contribution of such Contributor, 42 | if any, and such derivative works, in source code and object code form. 43 | b) Subject to the terms of this Agreement, each Contributor hereby grants 44 | Recipient a non-exclusive, worldwide, royalty-free patent license under 45 | Licensed Patents to make, use, sell, offer to sell, import and otherwise 46 | transfer the Contribution of such Contributor, if any, in source code and 47 | object code form. This patent license shall apply to the combination of 48 | the Contribution and the Program if, at the time the Contribution is 49 | added by the Contributor, such addition of the Contribution causes such 50 | combination to be covered by the Licensed Patents. The patent license 51 | shall not apply to any other combinations which include the Contribution. 52 | No hardware per se is licensed hereunder. 53 | c) Recipient understands that although each Contributor grants the licenses 54 | to its Contributions set forth herein, no assurances are provided by any 55 | Contributor that the Program does not infringe the patent or other 56 | intellectual property rights of any other entity. Each Contributor 57 | disclaims any liability to Recipient for claims brought by any other 58 | entity based on infringement of intellectual property rights or 59 | otherwise. As a condition to exercising the rights and licenses granted 60 | hereunder, each Recipient hereby assumes sole responsibility to secure 61 | any other intellectual property rights needed, if any. For example, if a 62 | third party patent license is required to allow Recipient to distribute 63 | the Program, it is Recipient's responsibility to acquire that license 64 | before distributing the Program. 65 | d) Each Contributor represents that to its knowledge it has sufficient 66 | copyright rights in its Contribution, if any, to grant the copyright 67 | license set forth in this Agreement. 68 | 69 | 3. REQUIREMENTS 70 | 71 | A Contributor may choose to distribute the Program in object code form under 72 | its own license agreement, provided that: 73 | 74 | a) it complies with the terms and conditions of this Agreement; and 75 | b) its license agreement: 76 | i) effectively disclaims on behalf of all Contributors all warranties 77 | and conditions, express and implied, including warranties or 78 | conditions of title and non-infringement, and implied warranties or 79 | conditions of merchantability and fitness for a particular purpose; 80 | ii) effectively excludes on behalf of all Contributors all liability for 81 | damages, including direct, indirect, special, incidental and 82 | consequential damages, such as lost profits; 83 | iii) states that any provisions which differ from this Agreement are 84 | offered by that Contributor alone and not by any other party; and 85 | iv) states that source code for the Program is available from such 86 | Contributor, and informs licensees how to obtain it in a reasonable 87 | manner on or through a medium customarily used for software exchange. 88 | 89 | When the Program is made available in source code form: 90 | 91 | a) it must be made available under this Agreement; and 92 | b) a copy of this Agreement must be included with each copy of the Program. 93 | Contributors may not remove or alter any copyright notices contained 94 | within the Program. 95 | 96 | Each Contributor must identify itself as the originator of its Contribution, 97 | if 98 | any, in a manner that reasonably allows subsequent Recipients to identify the 99 | originator of the Contribution. 100 | 101 | 4. COMMERCIAL DISTRIBUTION 102 | 103 | Commercial distributors of software may accept certain responsibilities with 104 | respect to end users, business partners and the like. While this license is 105 | intended to facilitate the commercial use of the Program, the Contributor who 106 | includes the Program in a commercial product offering should do so in a manner 107 | which does not create potential liability for other Contributors. Therefore, 108 | if a Contributor includes the Program in a commercial product offering, such 109 | Contributor ("Commercial Contributor") hereby agrees to defend and indemnify 110 | every other Contributor ("Indemnified Contributor") against any losses, 111 | damages and costs (collectively "Losses") arising from claims, lawsuits and 112 | other legal actions brought by a third party against the Indemnified 113 | Contributor to the extent caused by the acts or omissions of such Commercial 114 | Contributor in connection with its distribution of the Program in a commercial 115 | product offering. The obligations in this section do not apply to any claims 116 | or Losses relating to any actual or alleged intellectual property 117 | infringement. In order to qualify, an Indemnified Contributor must: 118 | a) promptly notify the Commercial Contributor in writing of such claim, and 119 | b) allow the Commercial Contributor to control, and cooperate with the 120 | Commercial Contributor in, the defense and any related settlement 121 | negotiations. The Indemnified Contributor may participate in any such claim at 122 | its own expense. 123 | 124 | For example, a Contributor might include the Program in a commercial product 125 | offering, Product X. That Contributor is then a Commercial Contributor. If 126 | that Commercial Contributor then makes performance claims, or offers 127 | warranties related to Product X, those performance claims and warranties are 128 | such Commercial Contributor's responsibility alone. Under this section, the 129 | Commercial Contributor would have to defend claims against the other 130 | Contributors related to those performance claims and warranties, and if a 131 | court requires any other Contributor to pay any damages as a result, the 132 | Commercial Contributor must pay those damages. 133 | 134 | 5. NO WARRANTY 135 | 136 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN 137 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR 138 | IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, 139 | NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each 140 | Recipient is solely responsible for determining the appropriateness of using 141 | and distributing the Program and assumes all risks associated with its 142 | exercise of rights under this Agreement , including but not limited to the 143 | risks and costs of program errors, compliance with applicable laws, damage to 144 | or loss of data, programs or equipment, and unavailability or interruption of 145 | operations. 146 | 147 | 6. DISCLAIMER OF LIABILITY 148 | 149 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY 150 | CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, 151 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION 152 | LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 153 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 154 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE 155 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY 156 | OF SUCH DAMAGES. 157 | 158 | 7. GENERAL 159 | 160 | If any provision of this Agreement is invalid or unenforceable under 161 | applicable law, it shall not affect the validity or enforceability of the 162 | remainder of the terms of this Agreement, and without further action by the 163 | parties hereto, such provision shall be reformed to the minimum extent 164 | necessary to make such provision valid and enforceable. 165 | 166 | If Recipient institutes patent litigation against any entity (including a 167 | cross-claim or counterclaim in a lawsuit) alleging that the Program itself 168 | (excluding combinations of the Program with other software or hardware) 169 | infringes such Recipient's patent(s), then such Recipient's rights granted 170 | under Section 2(b) shall terminate as of the date such litigation is filed. 171 | 172 | All Recipient's rights under this Agreement shall terminate if it fails to 173 | comply with any of the material terms or conditions of this Agreement and does 174 | not cure such failure in a reasonable period of time after becoming aware of 175 | such noncompliance. If all Recipient's rights under this Agreement terminate, 176 | Recipient agrees to cease use and distribution of the Program as soon as 177 | reasonably practicable. However, Recipient's obligations under this Agreement 178 | and any licenses granted by Recipient relating to the Program shall continue 179 | and survive. 180 | 181 | Everyone is permitted to copy and distribute copies of this Agreement, but in 182 | order to avoid inconsistency the Agreement is copyrighted and may only be 183 | modified in the following manner. The Agreement Steward reserves the right to 184 | publish new versions (including revisions) of this Agreement from time to 185 | time. No one other than the Agreement Steward has the right to modify this 186 | Agreement. The Eclipse Foundation is the initial Agreement Steward. The 187 | Eclipse Foundation may assign the responsibility to serve as the Agreement 188 | Steward to a suitable separate entity. Each new version of the Agreement will 189 | be given a distinguishing version number. The Program (including 190 | Contributions) may always be distributed subject to the version of the 191 | Agreement under which it was received. In addition, after a new version of the 192 | Agreement is published, Contributor may elect to distribute the Program 193 | (including its Contributions) under the new version. Except as expressly 194 | stated in Sections 2(a) and 2(b) above, Recipient receives no rights or 195 | licenses to the intellectual property of any Contributor under this Agreement, 196 | whether expressly, by implication, estoppel or otherwise. All rights in the 197 | Program not expressly granted under this Agreement are reserved. 198 | 199 | This Agreement is governed by the laws of the State of New York and the 200 | intellectual property laws of the United States of America. No party to this 201 | Agreement will bring a legal action under this Agreement more than one year 202 | after the cause of action arose. Each party waives its rights to a jury trial in 203 | any resulting litigation. 204 | --------------------------------------------------------------------------------