Skip to content

Instantly share code, notes, and snippets.

@matklad
Created July 7, 2016 15:27
Show Gist options
  • Save matklad/0685977255fad061d69bee8fa2a0e4dd to your computer and use it in GitHub Desktop.
Save matklad/0685977255fad061d69bee8fa2a0e4dd to your computer and use it in GitHub Desktop.
import org.apache.tools.ant.BuildException
import org.jetbrains.annotations.NotNull
///////////////////////////////////////////////////////////////////////////////////////////////////
// Buildscript
///////////////////////////////////////////////////////////////////////////////////////////////////
buildscript {
repositories {
mavenCentral()
maven { url 'http://dl.bintray.com/jetbrains/intellij-plugin-service' }
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
}
}
plugins {
id 'org.jetbrains.intellij' version "0.1.9"
id 'de.undercouch.download' version "2.1.0"
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Projects
///////////////////////////////////////////////////////////////////////////////////////////////////
allprojects {
// IntelliJ plugin configuration
apply plugin: 'org.jetbrains.intellij'
apply plugin: 'de.undercouch.download'
intellij {
pluginName 'intellij-rust'
instrumentCode = false
version ideaVersion
downloadSources Boolean.valueOf(downloadIdeaSources)
// FIXME: hack to support both IDEA 15 and IDEA 16.
// See https://github.com/intellij-rust/intellij-rust/issues/243
updateSinceUntilBuild = false
publish {
username publishUsername
password publishPassword
channel publishChannel
}
sandboxDirectory project.rootDir.canonicalPath + "/.sandbox"
}
apply plugin: 'java'
apply plugin: 'kotlin'
sourceCompatibility = javaVersion
targetCompatibility = javaVersion
tasks.withType(JavaCompile) { options.encoding = 'UTF-8' }
sourceSets {
main.java.srcDirs += "gen"
}
test {
useJUnit {
excludeCategories 'org.rust.Performance'
}
testLogging {
events "passed", "skipped", "failed"
exceptionFormat = 'full'
}
}
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
compile "org.jetbrains.kotlin:kotlin-runtime:$kotlinVersion"
testCompile "junit:junit:4.+"
testCompile 'org.assertj:assertj-core:3.2.0'
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// IDE support
///////////////////////////////////////////////////////////////////////////////////////////////////
apply plugin: 'idea'
idea {
project {
jdkName = javaVersion
languageLevel = javaVersion
}
module {
generatedSourceDirs += file('gen')
excludeDirs += file('.sandbox')
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Tasks
///////////////////////////////////////////////////////////////////////////////////////////////////
task downloadJetBrainsJflex(type: de.undercouch.gradle.tasks.download.Download) {
overwrite false
src([
// This is a patched version of Jflex which is used together with GrammarKit.
'https://raw.github.com/JetBrains/intellij-community/idea/162.1145/tools/lexer/jflex-1.7.0-SNAPSHOT.jar',
'https://raw.github.com/JetBrains/intellij-community/idea/162.1145/tools/lexer/idea-flex.skeleton'
])
def jflexDir = new File(projectDir, 'lib/jflex')
if (!jflexDir.exists()) {
jflexDir.mkdirs()
}
dest(jflexDir)
}
def lexerConfig(src, dst, lexerFileName) {
return {
dependsOn downloadJetBrainsJflex
classpath = files('lib/jflex/jflex-1.7.0-SNAPSHOT.jar')
main = "jflex.Main"
args = ["--skel", 'lib/jflex/idea-flex.skeleton',
"-d", dst,
src
]
inputs .file file(src)
outputs .dir file(dst + lexerFileName)
}
}
task generateRustLexer(type: JavaExec) {
configure lexerConfig(
"src/main/kotlin/org/rust/lang/core/lexer/RustLexer.flex",
"gen/org/rust/lang/core/lexer/",
"_RustLexer.java"
)
}
task generateRustDocHighlightingLexer(type: JavaExec) {
configure lexerConfig(
"src/main/kotlin/org/rust/lang/doc/lexer/RustDocHighlightingLexer.flex",
"gen/org/rust/lang/doc/lexer/",
"_RustDocHighlightingLexer.java"
)
}
task generateRustPsiAndParser(type: JavaExec) {
doFirst {
delete file("gen/org/rust/lang/core/psi/")
}
ext.src = "src/main/kotlin/org/rust/lang/core/grammar/rust.bnf"
ext.dstRoot = "gen"
main = "org.intellij.grammar.Main"
args = [ dstRoot, file(src) ]
inputs .file file(src)
outputs .dir fileTree(dir: dstRoot + '/org/rust/lang/core/', include: '**/*.java')
classpath (configurations.compile + files('lib/grammar-kit.jar'))
}
task generate {
dependsOn generateRustLexer, generateRustDocHighlightingLexer, generateRustPsiAndParser
}
class InstrumentHack implements Action<Task> {
private static final String FILTER_ANNOTATION_REGEXP_CLASS = 'com.intellij.ant.ClassFilterAnnotationRegexp'
private static final LOADER_REF = "java2.loader"
private final boolean myTestInstrumentation
InstrumentHack(boolean testInstrumentation) {
myTestInstrumentation = testInstrumentation
}
def mainSourceSet(project) {
JavaPluginConvention javaConvention = project.convention.getPlugin(JavaPluginConvention);
javaConvention.sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME)
}
def testSourceSet(project) {
JavaPluginConvention javaConvention = project.convention.getPlugin(JavaPluginConvention);
javaConvention.sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME)
}
@Override
void execute(Task task) {
def extension = task.project.extensions.getByType(org.jetbrains.intellij.IntelliJPluginExtension)
def classpath = task.project.files(
"$extension.ideaDependency.classes/lib/javac2.jar",
"$extension.ideaDependency.classes/lib/jdom.jar",
"$extension.ideaDependency.classes/lib/asm-all.jar",
"$extension.ideaDependency.classes/lib/jgoodies-forms.jar")
task.project.ant.taskdef(name: 'instrumentIdeaExtensions',
classpath: classpath.asPath,
loaderref: LOADER_REF,
classname: 'com.intellij.ant.InstrumentIdeaExtensions')
//noinspection GroovyAssignabilityCheck
def compileTask = task
boolean instrumentNotNull = prepareNotNullInstrumenting(compileTask, classpath)
def sourceSet = myTestInstrumentation ?
testSourceSet(compileTask.project).compiledBy(compileTask) :
mainSourceSet(compileTask.project).compiledBy(compileTask)
def srcDirs = existingDirs(sourceSet.allSource)
srcDirs.removeAll(existingDirs(sourceSet.resources))
if (!srcDirs.empty) {
instrumentCode(compileTask, srcDirs, instrumentNotNull)
}
}
private static HashSet<File> existingDirs(SourceDirectorySet sourceDirectorySet) {
return sourceDirectorySet.srcDirs.findAll { it.exists() }
}
private static boolean prepareNotNullInstrumenting(@NotNull Task compileTask,
@NotNull ConfigurableFileCollection classpath) {
try {
compileTask.project.ant.typedef(name: 'skip', classpath: classpath.asPath, loaderref: LOADER_REF,
classname: FILTER_ANNOTATION_REGEXP_CLASS)
} catch (BuildException e) {
def cause = e.getCause()
if (cause instanceof ClassNotFoundException && FILTER_ANNOTATION_REGEXP_CLASS.equals(cause.getMessage())) {
return false
} else {
throw e
}
}
return true
}
private static void instrumentCode(@NotNull AbstractCompile compileTask,
@NotNull Collection<File> srcDirs,
boolean instrumentNotNull) {
def headlessOldValue = System.setProperty('java.awt.headless', 'true')
compileTask.project.ant.instrumentIdeaExtensions(srcdir: compileTask.project.files(srcDirs).asPath,
destdir: compileTask.destinationDir, classpath: compileTask.classpath.asPath,
includeantruntime: false, instrumentNotNull: instrumentNotNull) {
if (instrumentNotNull) {
compileTask.project.ant.skip(pattern: 'kotlin/Metadata')
}
}
if (headlessOldValue != null) {
System.setProperty('java.awt.headless', headlessOldValue)
} else {
System.clearProperty('java.awt.headless')
}
}
}
compileKotlin.dependsOn generate
compileKotlin.doLast {
def a = new InstrumentHack(false)
a.execute(compileKotlin)
}
compileTestKotlin.dependsOn generate
task downloadRustSources(type: de.undercouch.gradle.tasks.download.Download) {
overwrite false
src 'https://github.com/rust-lang/rust/archive/1.7.0.zip'
dest new File(projectDir, "src/test/resources/rustc-src.zip")
}
test.dependsOn downloadRustSources
task performanceTest(type: Test, group: 'Verification', dependsOn: [classes, testClasses, downloadRustSources]) {
useJUnit {
includeCategories 'org.rust.Performance'
reports.html.destination = "$buildDir/reports/performanceTests"
}
testLogging {
events "passed", "skipped", "failed"
showStandardStreams = true
exceptionFormat = 'full'
}
outputs.upToDateWhen { false } // always execute task, even if already executed.
}
check.dependsOn performanceTest
///////////////////////////////////////////////////////////////////////////////////////////////////
// Misc
///////////////////////////////////////////////////////////////////////////////////////////////////
version = "${version}.$buildNumber"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment