aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorakosyakov2013-07-02 13:51:59 (EDT)
committerakosyakov2013-07-08 10:01:40 (EDT)
commit8488877a1850010f9d8dc5d7f28f5e184bfa8f3e (patch)
tree6b8a336a8615410b099a6eb125585c7e9227a790
parentc45a5e9b70a9241d11b87d41a2d9fb9f3fb4419e (diff)
downloadorg.eclipse.xtext-8488877a1850010f9d8dc5d7f28f5e184bfa8f3e.zip
org.eclipse.xtext-8488877a1850010f9d8dc5d7f28f5e184bfa8f3e.tar.gz
org.eclipse.xtext-8488877a1850010f9d8dc5d7f28f5e184bfa8f3e.tar.bz2
[Bug 411087]: resolved - added File System Access support for activerefs/changes/00/14200/5
annotations Change-Id: I6e7156c3d53c78304c273ef4fa3c2d4fd816b007 Signed-off-by: akosyakov <anton.kosyakov@itemis.de>
-rw-r--r--plugins/org.eclipse.xtend.core/META-INF/MANIFEST.MF1
-rw-r--r--plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/XtendRuntimeModule.java8
-rw-r--r--plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/TransformationContextImpl.xtend91
-rw-r--r--plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/declaration/CompilationUnitImpl.xtend15
-rw-r--r--plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/FileSystemAccessSPI.xtend50
-rw-r--r--plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/IOUtils.xtend29
-rw-r--r--plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/RuntimeFileHandle.xtend46
-rw-r--r--plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/RuntimeFileSystemAccessImpl.xtend26
-rw-r--r--plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/RuntimeFolderHandle.xtend36
-rw-r--r--plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/RuntimeResourceHandle.xtend36
-rw-r--r--plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/TransformationContextImpl.java22
-rw-r--r--plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/declaration/CompilationUnitImpl.java20
-rw-r--r--plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/AbstractFileSystemAccessImpl.java68
-rw-r--r--plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/FileSystemAccessSPI.java19
-rw-r--r--plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/IOUtils.java32
-rw-r--r--plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/RuntimeFileHandle.java97
-rw-r--r--plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/RuntimeFileSystemAccessImpl.java30
-rw-r--r--plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/RuntimeFolderHandle.java88
-rw-r--r--plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/RuntimeResourceHandle.java44
-rw-r--r--plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/XtendUiModule.java6
-rw-r--r--plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/macro/fsaccess/EclipseFileHandle.xtend85
-rw-r--r--plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/macro/fsaccess/EclipseFileSystemAccessImpl.xtend83
-rw-r--r--plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/macro/fsaccess/EclipseFolderHandle.xtend38
-rw-r--r--plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/macro/fsaccess/EclipseResourceHandle.xtend58
-rw-r--r--plugins/org.eclipse.xtend.ide/xtend-gen/org/eclipse/xtend/ide/macro/fsaccess/EclipseFileHandle.java201
-rw-r--r--plugins/org.eclipse.xtend.ide/xtend-gen/org/eclipse/xtend/ide/macro/fsaccess/EclipseFileSystemAccessImpl.java185
-rw-r--r--plugins/org.eclipse.xtend.ide/xtend-gen/org/eclipse/xtend/ide/macro/fsaccess/EclipseFolderHandle.java69
-rw-r--r--plugins/org.eclipse.xtend.ide/xtend-gen/org/eclipse/xtend/ide/macro/fsaccess/EclipseResourceHandle.java78
-rw-r--r--plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/TransformationContext.java5
-rw-r--r--plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/services/FileHandle.java70
-rw-r--r--plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/services/FileSystemAccess.java39
-rw-r--r--plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/services/FolderHandle.java39
-rw-r--r--plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/services/ResourceHandle.java36
-rw-r--r--plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/XtendCompile.java7
-rw-r--r--plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/XtendMavenModule.java7
-rw-r--r--plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/XtendTestCompile.java7
-rw-r--r--plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/macro/fsaccess/MavenFileSystemAccessImpl.java89
-rw-r--r--plugins/org.eclipse.xtend.maven.plugin/src/test/java/org/eclipse/xtend/maven/XtendCompilerMojoIT.java29
-rw-r--r--plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess-client/pom.xml36
-rw-r--r--plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess-client/src/main/.gitignore1
-rw-r--r--plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess-client/src/main/java/myusercode/UserCode.xtend5
-rw-r--r--plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess/pom.xml41
-rw-r--r--plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess/src/main/java/myannotation/MyAnnotation.xtend107
-rw-r--r--tests/org.eclipse.xtend.core.tests/src/org/eclipse/xtend/core/tests/macro/ActiveAnnotationsRuntimeTest.xtend34
-rw-r--r--tests/org.eclipse.xtend.ide.tests/src/org/eclipse/xtend/ide/tests/macros/ActiveAnnotationsProcessingInIDETest.xtend267
-rw-r--r--tests/org.eclipse.xtend.ide.tests/xtend-gen/org/eclipse/xtend/ide/tests/macros/ActiveAnnotationsProcessingInIDETest.java556
46 files changed, 2846 insertions, 90 deletions
diff --git a/plugins/org.eclipse.xtend.core/META-INF/MANIFEST.MF b/plugins/org.eclipse.xtend.core/META-INF/MANIFEST.MF
index 982af66..db2f5dc 100644
--- a/plugins/org.eclipse.xtend.core/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.xtend.core/META-INF/MANIFEST.MF
@@ -18,6 +18,7 @@ Export-Package: org.eclipse.xtend.core;x-internal:=true,
org.eclipse.xtend.core.linking;x-internal:=true,
org.eclipse.xtend.core.macro;x-internal:=true,
org.eclipse.xtend.core.macro.declaration;x-internal:=true,
+ org.eclipse.xtend.core.macro.fsaccess;x-internal:=true,
org.eclipse.xtend.core.naming;x-internal:=true,
org.eclipse.xtend.core.parser.antlr;x-internal:=true,
org.eclipse.xtend.core.parser.antlr.internal;x-internal:=true,
diff --git a/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/XtendRuntimeModule.java b/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/XtendRuntimeModule.java
index d5ae05f..6720d36 100644
--- a/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/XtendRuntimeModule.java
+++ b/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/XtendRuntimeModule.java
@@ -14,6 +14,8 @@ import org.eclipse.xtend.core.linking.Linker;
import org.eclipse.xtend.core.linking.LinkingProxyAwareResource;
import org.eclipse.xtend.core.linking.URIEncoder;
import org.eclipse.xtend.core.linking.XtendLinkingDiagnosticMessageProvider;
+import org.eclipse.xtend.core.macro.fsaccess.FileSystemAccessSPI;
+import org.eclipse.xtend.core.macro.fsaccess.RuntimeFileSystemAccessImpl;
import org.eclipse.xtend.core.naming.XtendQualifiedNameProvider;
import org.eclipse.xtend.core.resource.XtendLocationInFileProvider;
import org.eclipse.xtend.core.resource.XtendResourceDescriptionManager;
@@ -36,9 +38,9 @@ import org.eclipse.xtext.linking.lazy.LazyURIEncoder;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy;
import org.eclipse.xtext.resource.ILocationInFileProvider;
+import org.eclipse.xtext.resource.IResourceDescription.Manager;
import org.eclipse.xtext.resource.IResourceDescriptions;
import org.eclipse.xtext.resource.XtextResource;
-import org.eclipse.xtext.resource.IResourceDescription.Manager;
import org.eclipse.xtext.resource.impl.EagerResourceSetBasedResourceDescriptions;
import org.eclipse.xtext.scoping.IScopeProvider;
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
@@ -205,4 +207,8 @@ public class XtendRuntimeModule extends org.eclipse.xtend.core.AbstractXtendRunt
public void configureIResourceDescriptions(com.google.inject.Binder binder) {
binder.bind(IResourceDescriptions.class).to(EagerResourceSetBasedResourceDescriptions.class);
}
+
+ public Class<? extends FileSystemAccessSPI> bindFileSystemAccessPSI() {
+ return RuntimeFileSystemAccessImpl.class;
+ }
}
diff --git a/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/TransformationContextImpl.xtend b/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/TransformationContextImpl.xtend
index f89fc12..b6c5962 100644
--- a/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/TransformationContextImpl.xtend
+++ b/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/TransformationContextImpl.xtend
@@ -13,31 +13,45 @@ import org.eclipse.xtend.lib.macro.declaration.TypeReference
import org.eclipse.xtext.common.types.JvmIdentifiableElement
class TransformationContextImpl implements TransformationContext {
-
+
@Inject IXtendJvmAssociations associations
-
+
@Property CompilationUnitImpl unit
-
+
override isExternal(NamedElement element) {
!isSource(element) && !isGenerated(element)
}
-
+
override isGenerated(NamedElement element) {
switch element {
- JvmNamedElementImpl<? extends JvmIdentifiableElement> : {
+ JvmNamedElementImpl<? extends JvmIdentifiableElement>: {
return element.delegate.eResource == unit.xtendFile.eResource
}
- default: false
+ default:
+ false
}
}
-
+
+ override getSourceFolder() {
+ unit.sourceFolder
+ }
+
+ override getRootFolder() {
+ unit.rootFolder
+ }
+
+ override getTargetFolder() {
+ unit.targetFolder
+ }
+
override isSource(NamedElement element) {
element instanceof XtendNamedElementImpl<?>
}
-
+
override getPrimaryGeneratedJavaElement(NamedElement source) {
if (isSource(source)) {
- val derivedElement = associations.getJvmElements((source as XtendNamedElementImpl<?>).delegate).filter(JvmIdentifiableElement).head
+ val derivedElement = associations.getJvmElements((source as XtendNamedElementImpl<?>).delegate).filter(
+ JvmIdentifiableElement).head
if (derivedElement != null)
return unit.toNamedElement(derivedElement)
}
@@ -47,118 +61,117 @@ class TransformationContextImpl implements TransformationContext {
override addError(Element element, String message) {
unit.problemSupport.addError(element, message)
}
-
+
override addWarning(Element element, String message) {
unit.problemSupport.addWarning(element, message)
}
-
+
override getProblems(Element element) {
unit.problemSupport.getProblems(element)
}
-
+
override getAnyType() {
unit.typeReferenceProvider.anyType
}
-
+
override getList(TypeReference param) {
unit.typeReferenceProvider.getList(param)
}
-
+
override getObject() {
unit.typeReferenceProvider.getObject
}
-
+
override getPrimitiveBoolean() {
unit.typeReferenceProvider.primitiveBoolean
}
-
+
override getPrimitiveByte() {
unit.typeReferenceProvider.primitiveByte
}
-
+
override getPrimitiveChar() {
unit.typeReferenceProvider.primitiveChar
}
-
+
override getPrimitiveDouble() {
unit.typeReferenceProvider.primitiveDouble
}
-
+
override getPrimitiveFloat() {
unit.typeReferenceProvider.primitiveFloat
}
-
+
override getPrimitiveInt() {
unit.typeReferenceProvider.primitiveInt
}
-
+
override getPrimitiveLong() {
unit.typeReferenceProvider.primitiveLong
}
-
+
override getPrimitiveShort() {
unit.typeReferenceProvider.primitiveShort
}
-
+
override getPrimitiveVoid() {
unit.typeReferenceProvider.primitiveVoid
}
-
+
override getSet(TypeReference param) {
unit.typeReferenceProvider.getSet(param)
}
-
+
override getString() {
unit.typeReferenceProvider.string
}
-
+
override newArrayTypeReference(TypeReference componentType) {
unit.typeReferenceProvider.newArrayTypeReference(componentType)
}
-
+
override newTypeReference(String typeName, TypeReference... typeArguments) {
unit.typeReferenceProvider.newTypeReference(typeName, typeArguments)
}
-
+
override newTypeReference(Type typeDeclaration, TypeReference... typeArguments) {
unit.typeReferenceProvider.newTypeReference(typeDeclaration, typeArguments)
}
-
+
override newTypeReference(Class<?> clazz, TypeReference... typeArguments) {
unit.typeReferenceProvider.newTypeReference(clazz, typeArguments)
}
-
+
override newWildcardTypeReference() {
unit.typeReferenceProvider.newWildcardTypeReference
}
-
+
override newWildcardTypeReference(TypeReference upperBound) {
unit.typeReferenceProvider.newWildcardTypeReference(upperBound)
}
-
+
override findInterface(String qualifiedName) {
unit.typeLookup.findInterface(qualifiedName)
}
-
+
override findClass(String qualifiedName) {
unit.typeLookup.findClass(qualifiedName)
}
-
+
override findAnnotationType(String qualifiedName) {
unit.typeLookup.findAnnotationType(qualifiedName)
}
-
+
override findEnumerationType(String qualifiedName) {
unit.typeLookup.findEnumerationType(qualifiedName)
}
-
+
override findTypeGlobally(Class<? extends Object> clazz) {
unit.typeLookup.findTypeGlobally(clazz)
}
-
+
override findTypeGlobally(String typeName) {
unit.typeLookup.findTypeGlobally(typeName)
}
-
-}
+}
diff --git a/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/declaration/CompilationUnitImpl.xtend b/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/declaration/CompilationUnitImpl.xtend
index b2aa125..28755fb 100644
--- a/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/declaration/CompilationUnitImpl.xtend
+++ b/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/declaration/CompilationUnitImpl.xtend
@@ -88,6 +88,7 @@ import org.eclipse.xtext.xbase.typesystem.legacy.StandardTypeReferenceOwner
import org.eclipse.xtext.xbase.typesystem.references.LightweightTypeReference
import org.eclipse.xtext.xbase.typesystem.references.OwnedConverter
import org.eclipse.xtext.xbase.typesystem.util.CommonTypeComputationServices
+import org.eclipse.xtend.core.macro.fsaccess.FileSystemAccessSPI
class CompilationUnitImpl implements CompilationUnit {
@@ -140,6 +141,8 @@ class CompilationUnitImpl implements CompilationUnit {
@Inject IEObjectDocumentationProvider documentationProvider
@Inject IFileHeaderProvider fileHeaderProvider
@Inject JvmTypeExtensions typeExtensions;
+
+ @Inject FileSystemAccessSPI fileSystemAccess
@Property val ProblemSupport problemSupport = new ProblemSupportImpl(this)
@Property val TypeReferenceProvider typeReferenceProvider = new TypeReferenceProviderImpl(this)
@@ -479,5 +482,17 @@ class CompilationUnitImpl implements CompilationUnit {
return interpreter.evaluate(expression, null)
}
+ def getSourceFolder() {
+ fileSystemAccess.getSourceFolder(this)
+ }
+
+ def getRootFolder() {
+ fileSystemAccess.getRootFolder(this)
+ }
+
+ def getTargetFolder() {
+ fileSystemAccess.getTargetFolder(this)
+ }
+
}
diff --git a/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/FileSystemAccessSPI.xtend b/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/FileSystemAccessSPI.xtend
new file mode 100644
index 0000000..7c7cf20
--- /dev/null
+++ b/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/FileSystemAccessSPI.xtend
@@ -0,0 +1,50 @@
+package org.eclipse.xtend.core.macro.fsaccess
+
+import com.google.common.annotations.Beta
+import org.eclipse.jdt.annotation.NonNull
+import org.eclipse.xtend.core.macro.declaration.CompilationUnitImpl
+import org.eclipse.xtend.lib.macro.services.FolderHandle
+
+@Beta
+interface FileSystemAccessSPI {
+
+ @NonNull
+ def FolderHandle getSourceFolder(CompilationUnitImpl impl)
+
+ @NonNull
+ def FolderHandle getRootFolder(CompilationUnitImpl impl)
+
+ @NonNull
+ def FolderHandle getTargetFolder(CompilationUnitImpl impl)
+
+}
+
+abstract class AbstractFileSystemAccessImpl implements FileSystemAccessSPI {
+
+ override final getSourceFolder(CompilationUnitImpl it) {
+ getFolder([|doGetSourceFolder], "source")
+ }
+
+ abstract def FolderHandle doGetSourceFolder(CompilationUnitImpl it);
+
+ override final getRootFolder(CompilationUnitImpl it) {
+ getFolder([|doGetRootFolder], "root")
+ }
+
+ abstract def FolderHandle doGetRootFolder(CompilationUnitImpl it);
+
+ override final getTargetFolder(CompilationUnitImpl it) {
+ getFolder([|doGetTargetFolder], "target")
+ }
+
+ abstract def FolderHandle doGetTargetFolder(CompilationUnitImpl it);
+
+ def private FolderHandle getFolder(()=>FolderHandle it, String folderType) {
+ val folder = apply
+ if (folder == null) {
+ throw new IllegalStateException('''Could not find «folderType» folder.''')
+ }
+ folder
+ }
+
+}
diff --git a/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/IOUtils.xtend b/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/IOUtils.xtend
new file mode 100644
index 0000000..84e500b
--- /dev/null
+++ b/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/IOUtils.xtend
@@ -0,0 +1,29 @@
+package org.eclipse.xtend.core.macro.fsaccess
+
+import java.io.Closeable
+
+import static extension com.google.common.io.Closeables.*
+
+class IOUtils {
+
+ def static <T, C extends Closeable> T tryWith(()=>C provider, (C)=>T consumer) {
+ var closeable = null as C
+ try {
+ closeable = provider.apply()
+ return consumer.apply(closeable)
+ } finally {
+ closeable.closeQuietly
+ }
+ }
+
+ def static <C extends Closeable> tryWith(()=>C provider, (C)=>void consumer) {
+ var closeable = null as C
+ try {
+ closeable = provider.apply()
+ consumer.apply(closeable)
+ } finally {
+ closeable.closeQuietly
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/RuntimeFileHandle.xtend b/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/RuntimeFileHandle.xtend
new file mode 100644
index 0000000..f918587
--- /dev/null
+++ b/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/RuntimeFileHandle.xtend
@@ -0,0 +1,46 @@
+package org.eclipse.xtend.core.macro.fsaccess
+
+import java.io.File
+import java.io.InputStream
+import java.io.OutputStream
+import org.eclipse.xtend.lib.macro.services.FileHandle
+import org.eclipse.xtext.parser.IEncodingProvider
+import org.eclipse.xtext.xbase.lib.Functions.Function1
+import org.eclipse.xtext.xbase.lib.Procedures.Procedure1
+
+import static org.eclipse.xtend.core.macro.fsaccess.IOUtils.*
+
+import static extension com.google.common.io.Files.*
+
+class RuntimeFileHandle extends RuntimeResourceHandle implements FileHandle {
+
+ new(File file, IEncodingProvider encodingProvider) {
+ super(file, encodingProvider)
+ }
+
+ override getContents() {
+ file.toString(encoding)
+ }
+
+ override read(Procedure1<InputStream> function) {
+ tryWith([|file.newInputStreamSupplier.input], function)
+ }
+
+ override write(Procedure1<OutputStream> function) {
+ tryWith([|ensureFileCreated().newOutputStreamSupplier.output], function)
+ }
+
+ override writeContents(Function1<FileHandle, CharSequence> function) {
+ function.apply(this).write(ensureFileCreated(), encoding)
+ }
+
+ def ensureFileCreated() {
+ val file = file
+ if (!file.exists) {
+ file.createParentDirs
+ file.createNewFile
+ }
+ file
+ }
+
+}
diff --git a/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/RuntimeFileSystemAccessImpl.xtend b/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/RuntimeFileSystemAccessImpl.xtend
new file mode 100644
index 0000000..412e5d8
--- /dev/null
+++ b/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/RuntimeFileSystemAccessImpl.xtend
@@ -0,0 +1,26 @@
+package org.eclipse.xtend.core.macro.fsaccess
+
+import org.eclipse.xtend.core.macro.declaration.CompilationUnitImpl
+import org.eclipse.xtend.lib.macro.services.FileSystemAccess
+
+/**
+ * <p>
+ * This class is the stub for the Runtime mode.
+ * </p><p>
+ * Currently {@link FileSystemAccess} is used only in the context of active annotations processing with Eclipse or Maven.</p>
+ */
+class RuntimeFileSystemAccessImpl implements FileSystemAccessSPI {
+
+ override getSourceFolder(CompilationUnitImpl impl) {
+ throw new UnsupportedOperationException("FileSystemAccess is not supported in the Runtime mode")
+ }
+
+ override getRootFolder(CompilationUnitImpl impl) {
+ throw new UnsupportedOperationException("FileSystemAccess is not supported in the Runtime mode")
+ }
+
+ override getTargetFolder(CompilationUnitImpl impl) {
+ throw new UnsupportedOperationException("FileSystemAccess is not supported in the Runtime mode")
+ }
+
+}
diff --git a/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/RuntimeFolderHandle.xtend b/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/RuntimeFolderHandle.xtend
new file mode 100644
index 0000000..b77580d
--- /dev/null
+++ b/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/RuntimeFolderHandle.xtend
@@ -0,0 +1,36 @@
+package org.eclipse.xtend.core.macro.fsaccess
+
+import java.io.File
+import java.net.URI
+import org.eclipse.xtend.lib.macro.services.FolderHandle
+import org.eclipse.xtext.parser.IEncodingProvider
+
+class RuntimeFolderHandle extends RuntimeResourceHandle implements FolderHandle {
+
+ new(File file, IEncodingProvider encodingProvider) {
+ super(file, encodingProvider)
+ }
+
+ override getFile(String path) {
+ val file = new File(path.fullPath)
+ if (file.directory) {
+ val message = '''Given path is an existed folder (not a file): '«file.canonicalPath»'.'''
+ throw new IllegalStateException(message)
+ }
+ new RuntimeFileHandle(file, encodingProvider)
+ }
+
+ override getFolder(String path) {
+ val folder = new File(path.fullPath)
+ if (folder.file) {
+ val message = '''Given path is an existed file (not a folder): '«folder.canonicalPath»'.'''
+ throw new IllegalStateException(message)
+ }
+ new RuntimeFolderHandle(folder, encodingProvider)
+ }
+
+ def getFullPath(String path) {
+ new URI('''«getPath»/«path»''').normalize.path
+ }
+
+}
diff --git a/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/RuntimeResourceHandle.xtend b/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/RuntimeResourceHandle.xtend
new file mode 100644
index 0000000..87b8eb3
--- /dev/null
+++ b/plugins/org.eclipse.xtend.core/src/org/eclipse/xtend/core/macro/fsaccess/RuntimeResourceHandle.xtend
@@ -0,0 +1,36 @@
+package org.eclipse.xtend.core.macro.fsaccess
+
+import java.io.File
+import org.eclipse.xtend.lib.macro.services.ResourceHandle
+import org.eclipse.xtext.parser.IEncodingProvider
+
+import static extension java.nio.charset.Charset.*
+
+abstract class RuntimeResourceHandle implements ResourceHandle {
+
+ protected final File file
+
+ protected final IEncodingProvider encodingProvider
+
+ new(File file, IEncodingProvider encodingProvider) {
+ this.file = file
+ this.encodingProvider = encodingProvider
+ }
+
+ override exists() {
+ file.exists
+ }
+
+ override getName() {
+ file.name
+ }
+
+ override getPath() {
+ file.canonicalPath
+ }
+
+ def getEncoding() {
+ encodingProvider.getEncoding(null).forName
+ }
+
+}
diff --git a/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/TransformationContextImpl.java b/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/TransformationContextImpl.java
index 0dc48e5..2047147 100644
--- a/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/TransformationContextImpl.java
+++ b/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/TransformationContextImpl.java
@@ -23,6 +23,7 @@ import org.eclipse.xtend.lib.macro.declaration.MutableNamedElement;
import org.eclipse.xtend.lib.macro.declaration.NamedElement;
import org.eclipse.xtend.lib.macro.declaration.Type;
import org.eclipse.xtend.lib.macro.declaration.TypeReference;
+import org.eclipse.xtend.lib.macro.services.FolderHandle;
import org.eclipse.xtend.lib.macro.services.Problem;
import org.eclipse.xtend.lib.macro.services.ProblemSupport;
import org.eclipse.xtend.lib.macro.services.TypeReferenceProvider;
@@ -79,6 +80,24 @@ public class TransformationContextImpl implements TransformationContext {
return _switchResult;
}
+ public FolderHandle getSourceFolder() {
+ CompilationUnitImpl _unit = this.getUnit();
+ FolderHandle _sourceFolder = _unit.getSourceFolder();
+ return _sourceFolder;
+ }
+
+ public FolderHandle getRootFolder() {
+ CompilationUnitImpl _unit = this.getUnit();
+ FolderHandle _rootFolder = _unit.getRootFolder();
+ return _rootFolder;
+ }
+
+ public FolderHandle getTargetFolder() {
+ CompilationUnitImpl _unit = this.getUnit();
+ FolderHandle _targetFolder = _unit.getTargetFolder();
+ return _targetFolder;
+ }
+
public boolean isSource(final NamedElement element) {
return (element instanceof XtendNamedElementImpl<?>);
}
@@ -88,7 +107,8 @@ public class TransformationContextImpl implements TransformationContext {
if (_isSource) {
EObject _delegate = ((XtendNamedElementImpl<?>) source).getDelegate();
Set<EObject> _jvmElements = this.associations.getJvmElements(_delegate);
- Iterable<JvmIdentifiableElement> _filter = Iterables.<JvmIdentifiableElement>filter(_jvmElements, JvmIdentifiableElement.class);
+ Iterable<JvmIdentifiableElement> _filter = Iterables.<JvmIdentifiableElement>filter(_jvmElements,
+ JvmIdentifiableElement.class);
final JvmIdentifiableElement derivedElement = IterableExtensions.<JvmIdentifiableElement>head(_filter);
boolean _notEquals = (!Objects.equal(derivedElement, null));
if (_notEquals) {
diff --git a/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/declaration/CompilationUnitImpl.java b/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/declaration/CompilationUnitImpl.java
index 56490d2..8894eab 100644
--- a/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/declaration/CompilationUnitImpl.java
+++ b/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/declaration/CompilationUnitImpl.java
@@ -56,6 +56,7 @@ import org.eclipse.xtend.core.macro.declaration.XtendMethodDeclarationImpl;
import org.eclipse.xtend.core.macro.declaration.XtendParameterDeclarationImpl;
import org.eclipse.xtend.core.macro.declaration.XtendTypeDeclarationImpl;
import org.eclipse.xtend.core.macro.declaration.XtendTypeParameterDeclarationImpl;
+import org.eclipse.xtend.core.macro.fsaccess.FileSystemAccessSPI;
import org.eclipse.xtend.core.xtend.XtendAnnotationType;
import org.eclipse.xtend.core.xtend.XtendClass;
import org.eclipse.xtend.core.xtend.XtendConstructor;
@@ -84,6 +85,7 @@ import org.eclipse.xtend.lib.macro.declaration.TypeDeclaration;
import org.eclipse.xtend.lib.macro.declaration.TypeReference;
import org.eclipse.xtend.lib.macro.declaration.Visibility;
import org.eclipse.xtend.lib.macro.expression.Expression;
+import org.eclipse.xtend.lib.macro.services.FolderHandle;
import org.eclipse.xtend.lib.macro.services.ProblemSupport;
import org.eclipse.xtend.lib.macro.services.TypeReferenceProvider;
import org.eclipse.xtext.common.types.JvmAnnotationAnnotationValue;
@@ -236,6 +238,9 @@ public class CompilationUnitImpl implements CompilationUnit {
@Inject
private JvmTypeExtensions typeExtensions;
+ @Inject
+ private FileSystemAccessSPI fileSystemAccess;
+
private final ProblemSupport _problemSupport = new Function0<ProblemSupport>() {
public ProblemSupport apply() {
ProblemSupportImpl _problemSupportImpl = new ProblemSupportImpl(CompilationUnitImpl.this);
@@ -1123,4 +1128,19 @@ public class CompilationUnitImpl implements CompilationUnit {
public Object evaluate(final XExpression expression) {
return this.interpreter.evaluate(expression, null);
}
+
+ public FolderHandle getSourceFolder() {
+ FolderHandle _sourceFolder = this.fileSystemAccess.getSourceFolder(this);
+ return _sourceFolder;
+ }
+
+ public FolderHandle getRootFolder() {
+ FolderHandle _rootFolder = this.fileSystemAccess.getRootFolder(this);
+ return _rootFolder;
+ }
+
+ public FolderHandle getTargetFolder() {
+ FolderHandle _targetFolder = this.fileSystemAccess.getTargetFolder(this);
+ return _targetFolder;
+ }
}
diff --git a/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/AbstractFileSystemAccessImpl.java b/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/AbstractFileSystemAccessImpl.java
new file mode 100644
index 0000000..a4d2239
--- /dev/null
+++ b/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/AbstractFileSystemAccessImpl.java
@@ -0,0 +1,68 @@
+package org.eclipse.xtend.core.macro.fsaccess;
+
+import com.google.common.base.Objects;
+import org.eclipse.xtend.core.macro.declaration.CompilationUnitImpl;
+import org.eclipse.xtend.core.macro.fsaccess.FileSystemAccessSPI;
+import org.eclipse.xtend.lib.macro.services.FolderHandle;
+import org.eclipse.xtend2.lib.StringConcatenation;
+import org.eclipse.xtext.xbase.lib.Functions.Function0;
+
+@SuppressWarnings("all")
+public abstract class AbstractFileSystemAccessImpl implements FileSystemAccessSPI {
+ public final FolderHandle getSourceFolder(final CompilationUnitImpl it) {
+ final Function0<FolderHandle> _function = new Function0<FolderHandle>() {
+ public FolderHandle apply() {
+ FolderHandle _doGetSourceFolder = AbstractFileSystemAccessImpl.this.doGetSourceFolder(it);
+ return _doGetSourceFolder;
+ }
+ };
+ FolderHandle _folder = this.getFolder(_function, "source");
+ return _folder;
+ }
+
+ public abstract FolderHandle doGetSourceFolder(final CompilationUnitImpl it);
+
+ public final FolderHandle getRootFolder(final CompilationUnitImpl it) {
+ final Function0<FolderHandle> _function = new Function0<FolderHandle>() {
+ public FolderHandle apply() {
+ FolderHandle _doGetRootFolder = AbstractFileSystemAccessImpl.this.doGetRootFolder(it);
+ return _doGetRootFolder;
+ }
+ };
+ FolderHandle _folder = this.getFolder(_function, "root");
+ return _folder;
+ }
+
+ public abstract FolderHandle doGetRootFolder(final CompilationUnitImpl it);
+
+ public final FolderHandle getTargetFolder(final CompilationUnitImpl it) {
+ final Function0<FolderHandle> _function = new Function0<FolderHandle>() {
+ public FolderHandle apply() {
+ FolderHandle _doGetTargetFolder = AbstractFileSystemAccessImpl.this.doGetTargetFolder(it);
+ return _doGetTargetFolder;
+ }
+ };
+ FolderHandle _folder = this.getFolder(_function, "target");
+ return _folder;
+ }
+
+ public abstract FolderHandle doGetTargetFolder(final CompilationUnitImpl it);
+
+ private FolderHandle getFolder(final Function0<? extends FolderHandle> it, final String folderType) {
+ FolderHandle _xblockexpression = null;
+ {
+ final FolderHandle folder = it.apply();
+ boolean _equals = Objects.equal(folder, null);
+ if (_equals) {
+ StringConcatenation _builder = new StringConcatenation();
+ _builder.append("Could not find ");
+ _builder.append(folderType, "");
+ _builder.append(" folder.");
+ IllegalStateException _illegalStateException = new IllegalStateException(_builder.toString());
+ throw _illegalStateException;
+ }
+ _xblockexpression = (folder);
+ }
+ return _xblockexpression;
+ }
+}
diff --git a/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/FileSystemAccessSPI.java b/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/FileSystemAccessSPI.java
new file mode 100644
index 0000000..af93a70
--- /dev/null
+++ b/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/FileSystemAccessSPI.java
@@ -0,0 +1,19 @@
+package org.eclipse.xtend.core.macro.fsaccess;
+
+import com.google.common.annotations.Beta;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.xtend.core.macro.declaration.CompilationUnitImpl;
+import org.eclipse.xtend.lib.macro.services.FolderHandle;
+
+@Beta
+@SuppressWarnings("all")
+public interface FileSystemAccessSPI {
+ @NonNull
+ public abstract FolderHandle getSourceFolder(final CompilationUnitImpl impl);
+
+ @NonNull
+ public abstract FolderHandle getRootFolder(final CompilationUnitImpl impl);
+
+ @NonNull
+ public abstract FolderHandle getTargetFolder(final CompilationUnitImpl impl);
+}
diff --git a/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/IOUtils.java b/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/IOUtils.java
new file mode 100644
index 0000000..5e944d4
--- /dev/null
+++ b/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/IOUtils.java
@@ -0,0 +1,32 @@
+package org.eclipse.xtend.core.macro.fsaccess;
+
+import com.google.common.io.Closeables;
+import java.io.Closeable;
+import org.eclipse.xtext.xbase.lib.Functions.Function0;
+import org.eclipse.xtext.xbase.lib.Functions.Function1;
+import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
+
+@SuppressWarnings("all")
+public class IOUtils {
+ public static <T extends Object, C extends Closeable> T tryWith(final Function0<? extends C> provider, final Function1<? super C,? extends T> consumer) {
+ C closeable = ((C) null);
+ try {
+ C _apply = provider.apply();
+ closeable = _apply;
+ return consumer.apply(closeable);
+ } finally {
+ Closeables.closeQuietly(closeable);
+ }
+ }
+
+ public static <C extends Closeable> void tryWith(final Function0<? extends C> provider, final Procedure1<? super C> consumer) {
+ C closeable = ((C) null);
+ try {
+ C _apply = provider.apply();
+ closeable = _apply;
+ consumer.apply(closeable);
+ } finally {
+ Closeables.closeQuietly(closeable);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/RuntimeFileHandle.java b/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/RuntimeFileHandle.java
new file mode 100644
index 0000000..d4a04f5
--- /dev/null
+++ b/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/RuntimeFileHandle.java
@@ -0,0 +1,97 @@
+package org.eclipse.xtend.core.macro.fsaccess;
+
+import com.google.common.io.Files;
+import com.google.common.io.InputSupplier;
+import com.google.common.io.OutputSupplier;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+import org.eclipse.xtend.core.macro.fsaccess.IOUtils;
+import org.eclipse.xtend.core.macro.fsaccess.RuntimeResourceHandle;
+import org.eclipse.xtend.lib.macro.services.FileHandle;
+import org.eclipse.xtext.parser.IEncodingProvider;
+import org.eclipse.xtext.xbase.lib.Exceptions;
+import org.eclipse.xtext.xbase.lib.Functions.Function0;
+import org.eclipse.xtext.xbase.lib.Functions.Function1;
+import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
+
+@SuppressWarnings("all")
+public class RuntimeFileHandle extends RuntimeResourceHandle implements FileHandle {
+ public RuntimeFileHandle(final File file, final IEncodingProvider encodingProvider) {
+ super(file, encodingProvider);
+ }
+
+ public String getContents() {
+ try {
+ Charset _encoding = this.getEncoding();
+ String _string = Files.toString(this.file, _encoding);
+ return _string;
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+
+ public void read(final Procedure1<InputStream> function) {
+ final Function0<FileInputStream> _function = new Function0<FileInputStream>() {
+ public FileInputStream apply() {
+ try {
+ InputSupplier<FileInputStream> _newInputStreamSupplier = Files.newInputStreamSupplier(RuntimeFileHandle.this.file);
+ FileInputStream _input = _newInputStreamSupplier.getInput();
+ return _input;
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+ };
+ IOUtils.<InputStream>tryWith(_function, function);
+ }
+
+ public void write(final Procedure1<OutputStream> function) {
+ final Function0<FileOutputStream> _function = new Function0<FileOutputStream>() {
+ public FileOutputStream apply() {
+ try {
+ File _ensureFileCreated = RuntimeFileHandle.this.ensureFileCreated();
+ OutputSupplier<FileOutputStream> _newOutputStreamSupplier = Files.newOutputStreamSupplier(_ensureFileCreated);
+ FileOutputStream _output = _newOutputStreamSupplier.getOutput();
+ return _output;
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+ };
+ IOUtils.<OutputStream>tryWith(_function, function);
+ }
+
+ public void writeContents(final Function1<FileHandle,CharSequence> function) {
+ try {
+ CharSequence _apply = function.apply(this);
+ File _ensureFileCreated = this.ensureFileCreated();
+ Charset _encoding = this.getEncoding();
+ Files.write(_apply, _ensureFileCreated, _encoding);
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+
+ public File ensureFileCreated() {
+ try {
+ File _xblockexpression = null;
+ {
+ final File file = this.file;
+ boolean _exists = file.exists();
+ boolean _not = (!_exists);
+ if (_not) {
+ Files.createParentDirs(file);
+ file.createNewFile();
+ }
+ _xblockexpression = (file);
+ }
+ return _xblockexpression;
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/RuntimeFileSystemAccessImpl.java b/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/RuntimeFileSystemAccessImpl.java
new file mode 100644
index 0000000..ad36892
--- /dev/null
+++ b/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/RuntimeFileSystemAccessImpl.java
@@ -0,0 +1,30 @@
+package org.eclipse.xtend.core.macro.fsaccess;
+
+import org.eclipse.xtend.core.macro.declaration.CompilationUnitImpl;
+import org.eclipse.xtend.core.macro.fsaccess.FileSystemAccessSPI;
+import org.eclipse.xtend.lib.macro.services.FileSystemAccess;
+import org.eclipse.xtend.lib.macro.services.FolderHandle;
+
+/**
+ * <p>
+ * This class is the stub for the Runtime mode.
+ * </p><p>
+ * Currently {@link FileSystemAccess} is used only in the context of active annotations processing with Eclipse or Maven.</p>
+ */
+@SuppressWarnings("all")
+public class RuntimeFileSystemAccessImpl implements FileSystemAccessSPI {
+ public FolderHandle getSourceFolder(final CompilationUnitImpl impl) {
+ UnsupportedOperationException _unsupportedOperationException = new UnsupportedOperationException("FileSystemAccess is not supported in the Runtime mode");
+ throw _unsupportedOperationException;
+ }
+
+ public FolderHandle getRootFolder(final CompilationUnitImpl impl) {
+ UnsupportedOperationException _unsupportedOperationException = new UnsupportedOperationException("FileSystemAccess is not supported in the Runtime mode");
+ throw _unsupportedOperationException;
+ }
+
+ public FolderHandle getTargetFolder(final CompilationUnitImpl impl) {
+ UnsupportedOperationException _unsupportedOperationException = new UnsupportedOperationException("FileSystemAccess is not supported in the Runtime mode");
+ throw _unsupportedOperationException;
+ }
+}
diff --git a/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/RuntimeFolderHandle.java b/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/RuntimeFolderHandle.java
new file mode 100644
index 0000000..6661535
--- /dev/null
+++ b/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/RuntimeFolderHandle.java
@@ -0,0 +1,88 @@
+package org.eclipse.xtend.core.macro.fsaccess;
+
+import java.io.File;
+import java.net.URI;
+import org.eclipse.xtend.core.macro.fsaccess.RuntimeFileHandle;
+import org.eclipse.xtend.core.macro.fsaccess.RuntimeResourceHandle;
+import org.eclipse.xtend.lib.macro.services.FileHandle;
+import org.eclipse.xtend.lib.macro.services.FolderHandle;
+import org.eclipse.xtend2.lib.StringConcatenation;
+import org.eclipse.xtext.parser.IEncodingProvider;
+import org.eclipse.xtext.xbase.lib.Exceptions;
+
+@SuppressWarnings("all")
+public class RuntimeFolderHandle extends RuntimeResourceHandle implements FolderHandle {
+ public RuntimeFolderHandle(final File file, final IEncodingProvider encodingProvider) {
+ super(file, encodingProvider);
+ }
+
+ public FileHandle getFile(final String path) {
+ try {
+ RuntimeFileHandle _xblockexpression = null;
+ {
+ String _fullPath = this.getFullPath(path);
+ File _file = new File(_fullPath);
+ final File file = _file;
+ boolean _isDirectory = file.isDirectory();
+ if (_isDirectory) {
+ StringConcatenation _builder = new StringConcatenation();
+ _builder.append("Given path is an existed folder (not a file): \'");
+ String _canonicalPath = file.getCanonicalPath();
+ _builder.append(_canonicalPath, "");
+ _builder.append("\'.");
+ final String message = _builder.toString();
+ IllegalStateException _illegalStateException = new IllegalStateException(message);
+ throw _illegalStateException;
+ }
+ RuntimeFileHandle _runtimeFileHandle = new RuntimeFileHandle(file, this.encodingProvider);
+ _xblockexpression = (_runtimeFileHandle);
+ }
+ return _xblockexpression;
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+
+ public FolderHandle getFolder(final String path) {
+ try {
+ RuntimeFolderHandle _xblockexpression = null;
+ {
+ String _fullPath = this.getFullPath(path);
+ File _file = new File(_fullPath);
+ final File folder = _file;
+ boolean _isFile = folder.isFile();
+ if (_isFile) {
+ StringConcatenation _builder = new StringConcatenation();
+ _builder.append("Given path is an existed file (not a folder): \'");
+ String _canonicalPath = folder.getCanonicalPath();
+ _builder.append(_canonicalPath, "");
+ _builder.append("\'.");
+ final String message = _builder.toString();
+ IllegalStateException _illegalStateException = new IllegalStateException(message);
+ throw _illegalStateException;
+ }
+ RuntimeFolderHandle _runtimeFolderHandle = new RuntimeFolderHandle(folder, this.encodingProvider);
+ _xblockexpression = (_runtimeFolderHandle);
+ }
+ return _xblockexpression;
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+
+ public String getFullPath(final String path) {
+ try {
+ StringConcatenation _builder = new StringConcatenation();
+ String _path = this.getPath();
+ _builder.append(_path, "");
+ _builder.append("/");
+ _builder.append(path, "");
+ URI _uRI = new URI(_builder.toString());
+ URI _normalize = _uRI.normalize();
+ String _path_1 = _normalize.getPath();
+ return _path_1;
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/RuntimeResourceHandle.java b/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/RuntimeResourceHandle.java
new file mode 100644
index 0000000..d38e337
--- /dev/null
+++ b/plugins/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/macro/fsaccess/RuntimeResourceHandle.java
@@ -0,0 +1,44 @@
+package org.eclipse.xtend.core.macro.fsaccess;
+
+import java.io.File;
+import java.nio.charset.Charset;
+import org.eclipse.xtend.lib.macro.services.ResourceHandle;
+import org.eclipse.xtext.parser.IEncodingProvider;
+import org.eclipse.xtext.xbase.lib.Exceptions;
+
+@SuppressWarnings("all")
+public abstract class RuntimeResourceHandle implements ResourceHandle {
+ protected final File file;
+
+ protected final IEncodingProvider encodingProvider;
+
+ public RuntimeResourceHandle(final File file, final IEncodingProvider encodingProvider) {
+ this.file = file;
+ this.encodingProvider = encodingProvider;
+ }
+
+ public boolean exists() {
+ boolean _exists = this.file.exists();
+ return _exists;
+ }
+
+ public String getName() {
+ String _name = this.file.getName();
+ return _name;
+ }
+
+ public String getPath() {
+ try {
+ String _canonicalPath = this.file.getCanonicalPath();
+ return _canonicalPath;
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+
+ public Charset getEncoding() {
+ String _encoding = this.encodingProvider.getEncoding(null);
+ Charset _forName = Charset.forName(_encoding);
+ return _forName;
+ }
+}
diff --git a/plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/XtendUiModule.java b/plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/XtendUiModule.java
index 03e0fa1..0898819 100644
--- a/plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/XtendUiModule.java
+++ b/plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/XtendUiModule.java
@@ -12,6 +12,7 @@ import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
import org.eclipse.xtend.core.formatting.FormatterPreferenceValuesProvider;
import org.eclipse.xtend.core.macro.ProcessorInstanceForJvmTypeProvider;
+import org.eclipse.xtend.core.macro.fsaccess.FileSystemAccessSPI;
import org.eclipse.xtend.ide.autoedit.AutoEditStrategyProvider;
import org.eclipse.xtend.ide.autoedit.TokenTypeToPartitionMapper;
import org.eclipse.xtend.ide.builder.JavaProjectPreferencesInitializer;
@@ -49,6 +50,7 @@ import org.eclipse.xtend.ide.hover.XtendHoverSignatureProvider;
import org.eclipse.xtend.ide.hyperlinking.XtendHyperlinkHelper;
import org.eclipse.xtend.ide.labeling.XtendLabelProvider;
import org.eclipse.xtend.ide.macro.JdtBasedProcessorProvider;
+import org.eclipse.xtend.ide.macro.fsaccess.EclipseFileSystemAccessImpl;
import org.eclipse.xtend.ide.outline.ShowSyntheticMembersContribution;
import org.eclipse.xtend.ide.outline.XtendOutlineNodeComparator;
import org.eclipse.xtend.ide.outline.XtendOutlinePage;
@@ -416,4 +418,8 @@ public class XtendUiModule extends org.eclipse.xtend.ide.AbstractXtendUiModule {
public Class<? extends ICompletionProposalComparator> bindICompletionProposalComparator() {
return OperatorAwareComparator.class;
}
+
+ public Class<? extends FileSystemAccessSPI> bindFileSystemAccessPSI() {
+ return EclipseFileSystemAccessImpl.class;
+ }
}
diff --git a/plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/macro/fsaccess/EclipseFileHandle.xtend b/plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/macro/fsaccess/EclipseFileHandle.xtend
new file mode 100644
index 0000000..e2e0c8d
--- /dev/null
+++ b/plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/macro/fsaccess/EclipseFileHandle.xtend
@@ -0,0 +1,85 @@
+package org.eclipse.xtend.ide.macro.fsaccess
+
+import com.google.common.io.CharStreams
+import java.io.BufferedInputStream
+import java.io.BufferedWriter
+import java.io.ByteArrayInputStream
+import java.io.ByteArrayOutputStream
+import java.io.InputStream
+import java.io.InputStreamReader
+import java.io.OutputStream
+import java.io.OutputStreamWriter
+import org.eclipse.core.resources.IContainer
+import org.eclipse.core.resources.IFile
+import org.eclipse.core.resources.IFolder
+import org.eclipse.core.resources.IProject
+import org.eclipse.core.runtime.IPath
+import org.eclipse.core.runtime.NullProgressMonitor
+import org.eclipse.xtend.lib.macro.services.FileHandle
+import org.eclipse.xtext.parser.IEncodingProvider
+import org.eclipse.xtext.xbase.lib.Functions.Function1
+import org.eclipse.xtext.xbase.lib.Procedures.Procedure1
+
+import static org.eclipse.xtend.core.macro.fsaccess.IOUtils.*
+
+import static extension com.google.common.io.CharStreams.*
+
+class EclipseFileHandle extends EclipseResourceHandle implements FileHandle {
+
+ new(IProject project, IPath path, IEncodingProvider encodingProvider) {
+ super(project, path, encodingProvider)
+ }
+
+ override getMember() {
+ file
+ }
+
+ override getContents() {
+ CharStreams.toString(new InputStreamReader(file.contents, encoding))
+ }
+
+ override read(Procedure1<InputStream> function) {
+ tryWith([|file.contents], function)
+ }
+
+ override writeContents(Function1<FileHandle, CharSequence> function) {
+ write [ outputStream |
+ function.apply(this).write [ |
+ new BufferedWriter(new OutputStreamWriter(outputStream))
+ ]
+ ]
+ }
+
+ override write(Procedure1<OutputStream> function) {
+ tryWith([|new ByteArrayOutputStream]) [
+ function.apply(it)
+ tryWith([|new BufferedInputStream(new ByteArrayInputStream(toByteArray))]) [
+ file.ensureCreated.setContents(it, true, true, new NullProgressMonitor)
+ ]
+ ]
+ }
+
+ def dispatch IFile ensureCreated(IFile it) {
+ if (!exists) {
+ parent.ensureCreated
+ create(new ByteArrayInputStream(newByteArrayOfSize(0)), true, new NullProgressMonitor)
+ }
+ file
+ }
+
+ def dispatch IFile ensureCreated(IFolder it) {
+ if (!exists) {
+ parent.ensureCreated
+ create(true, true, new NullProgressMonitor)
+ }
+ null
+ }
+
+ def dispatch IFile ensureCreated(IContainer it) {
+ if (!exists) {
+ throw new IllegalStateException('''Container does not exist: '«path»'.''')
+ }
+ null
+ }
+
+}
diff --git a/plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/macro/fsaccess/EclipseFileSystemAccessImpl.xtend b/plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/macro/fsaccess/EclipseFileSystemAccessImpl.xtend
new file mode 100644
index 0000000..c145e9a
--- /dev/null
+++ b/plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/macro/fsaccess/EclipseFileSystemAccessImpl.xtend
@@ -0,0 +1,83 @@
+package org.eclipse.xtend.ide.macro.fsaccess
+
+import com.google.inject.Inject
+import org.eclipse.core.resources.IFile
+import org.eclipse.jdt.core.IClasspathEntry
+import org.eclipse.xtend.core.macro.declaration.CompilationUnitImpl
+import org.eclipse.xtend.core.macro.fsaccess.AbstractFileSystemAccessImpl
+import org.eclipse.xtext.builder.EclipseOutputConfigurationProvider
+import org.eclipse.xtext.common.types.access.jdt.IJavaProjectProvider
+import org.eclipse.xtext.parser.IEncodingProvider
+import org.eclipse.xtext.ui.resource.IStorage2UriMapper
+
+class EclipseFileSystemAccessImpl extends AbstractFileSystemAccessImpl {
+
+ @Inject
+ private IStorage2UriMapper mapper
+
+ @Inject
+ private IEncodingProvider encodingProvider
+
+ @Inject
+ private IJavaProjectProvider javaProjectProvider
+
+ @Inject
+ private EclipseOutputConfigurationProvider outputConfigurationProvider
+
+ override doGetSourceFolder(CompilationUnitImpl it) {
+ val file = file
+ if (file == null) {
+ return null
+ }
+ val sourcePath = sourcePath
+ if (sourcePath == null) {
+ return null
+ }
+ new EclipseFolderHandle(file.project, sourcePath, encodingProvider)
+ }
+
+ override doGetRootFolder(CompilationUnitImpl it) {
+ val file = file
+ if (file == null) {
+ return null
+ }
+ new EclipseFolderHandle(file.project, file.project.projectRelativePath, encodingProvider)
+ }
+
+ override doGetTargetFolder(CompilationUnitImpl it) {
+ val file = file
+ if (file == null) {
+ return null
+ }
+ val directory = file.outputConfig.outputDirectory;
+ val path = sourcePath.append("../" + directory);
+ new EclipseFolderHandle(file.project, path, encodingProvider)
+ }
+
+ def getSourcePath(CompilationUnitImpl it) {
+ val filePath = file?.fullPath
+ if (filePath == null) {
+ return null
+ }
+ javaProject.getResolvedClasspath(true).filter [
+ entryKind == IClasspathEntry.CPE_SOURCE && path.isPrefixOf(filePath)
+ ].head?.path.removeFirstSegments(1)
+ }
+
+ def getOutputConfig(IFile it) {
+ outputConfigurationProvider.getOutputConfigurations(project).head
+ }
+
+ def getFile(CompilationUnitImpl it) {
+ storages.map[first].filter(IFile).head
+ }
+
+ def getStorages(CompilationUnitImpl it) {
+ mapper.getStorages(getXtendFile.eResource.getURI)
+ }
+
+ def getJavaProject(CompilationUnitImpl it) {
+ javaProjectProvider.getJavaProject(xtendFile.eResource.resourceSet)
+ }
+
+}
diff --git a/plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/macro/fsaccess/EclipseFolderHandle.xtend b/plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/macro/fsaccess/EclipseFolderHandle.xtend
new file mode 100644
index 0000000..2e1664c
--- /dev/null
+++ b/plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/macro/fsaccess/EclipseFolderHandle.xtend
@@ -0,0 +1,38 @@
+package org.eclipse.xtend.ide.macro.fsaccess
+
+import org.eclipse.core.resources.IProject
+import org.eclipse.core.runtime.IPath
+import org.eclipse.xtend.lib.macro.services.FolderHandle
+import org.eclipse.xtext.parser.IEncodingProvider
+
+class EclipseFolderHandle extends EclipseResourceHandle implements FolderHandle {
+
+ new(IProject project, IPath path, IEncodingProvider encodingProvider) {
+ super(project, path, encodingProvider)
+ }
+
+ override getFile(String path) {
+ val filePath = this.path.append(path)
+ val folder = project.getFolder(filePath)
+ if (folder.exists) {
+ throw new IllegalStateException(
+ '''Given path is an existed folder (not a file): '«folder.location.makeAbsolute»'.''')
+ }
+ new EclipseFileHandle(project, filePath, encodingProvider)
+ }
+
+ override getFolder(String path) {
+ val filePath = this.path.append(path)
+ val file = project.getFile(filePath)
+ if (file.exists) {
+ throw new IllegalStateException(
+ '''Given path is an existed file (not a folder): '«file.location.makeAbsolute»'.''')
+ }
+ new EclipseFolderHandle(project, filePath, encodingProvider)
+ }
+
+ override getMember() {
+ folder
+ }
+
+}
diff --git a/plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/macro/fsaccess/EclipseResourceHandle.xtend b/plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/macro/fsaccess/EclipseResourceHandle.xtend
new file mode 100644
index 0000000..96f5695
--- /dev/null
+++ b/plugins/org.eclipse.xtend.ide/src/org/eclipse/xtend/ide/macro/fsaccess/EclipseResourceHandle.xtend
@@ -0,0 +1,58 @@
+package org.eclipse.xtend.ide.macro.fsaccess
+
+import org.eclipse.core.resources.IProject
+import org.eclipse.core.resources.IResource
+import org.eclipse.core.runtime.IPath
+import org.eclipse.emf.common.util.URI
+import org.eclipse.xtend.lib.macro.services.ResourceHandle
+import org.eclipse.xtext.parser.IEncodingProvider
+
+abstract class EclipseResourceHandle implements ResourceHandle {
+
+ protected final IPath path
+
+ protected final IProject project
+
+ protected final IEncodingProvider encodingProvider
+
+ new(IProject project, IPath path, IEncodingProvider encodingProvider) {
+ this.project = project
+ this.path = path;
+ this.encodingProvider = encodingProvider
+ }
+
+ override exists() {
+ project.exists(path)
+ }
+
+ override getName() {
+ location.lastSegment
+ }
+
+ override getPath() {
+ location.toString
+ }
+
+ def getFile() {
+ project.getFile(path)
+ }
+
+ def getFolder() {
+ project.getFolder(path)
+ }
+
+ def getLocation() {
+ var resource = project.findMember(path)
+ if (resource == null) {
+ resource = member
+ }
+ resource.location.makeAbsolute
+ }
+
+ def abstract IResource getMember();
+
+ def getEncoding() {
+ encodingProvider.getEncoding(URI.createFileURI(getPath))
+ }
+
+}
diff --git a/plugins/org.eclipse.xtend.ide/xtend-gen/org/eclipse/xtend/ide/macro/fsaccess/EclipseFileHandle.java b/plugins/org.eclipse.xtend.ide/xtend-gen/org/eclipse/xtend/ide/macro/fsaccess/EclipseFileHandle.java
new file mode 100644
index 0000000..e6848ca
--- /dev/null
+++ b/plugins/org.eclipse.xtend.ide/xtend-gen/org/eclipse/xtend/ide/macro/fsaccess/EclipseFileHandle.java
@@ -0,0 +1,201 @@
+package org.eclipse.xtend.ide.macro.fsaccess;
+
+import com.google.common.io.CharStreams;
+import com.google.common.io.OutputSupplier;
+import java.io.BufferedInputStream;
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.util.Arrays;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.xtend.core.macro.fsaccess.IOUtils;
+import org.eclipse.xtend.ide.macro.fsaccess.EclipseResourceHandle;
+import org.eclipse.xtend.lib.macro.services.FileHandle;
+import org.eclipse.xtend2.lib.StringConcatenation;
+import org.eclipse.xtext.parser.IEncodingProvider;
+import org.eclipse.xtext.xbase.lib.Exceptions;
+import org.eclipse.xtext.xbase.lib.Functions.Function0;
+import org.eclipse.xtext.xbase.lib.Functions.Function1;
+import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
+
+@SuppressWarnings("all")
+public class EclipseFileHandle extends EclipseResourceHandle implements FileHandle {
+ public EclipseFileHandle(final IProject project, final IPath path, final IEncodingProvider encodingProvider) {
+ super(project, path, encodingProvider);
+ }
+
+ public IResource getMember() {
+ IFile _file = this.getFile();
+ return _file;
+ }
+
+ public String getContents() {
+ try {
+ IFile _file = this.getFile();
+ InputStream _contents = _file.getContents();
+ String _encoding = this.getEncoding();
+ InputStreamReader _inputStreamReader = new InputStreamReader(_contents, _encoding);
+ String _string = CharStreams.toString(_inputStreamReader);
+ return _string;
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+
+ public void read(final Procedure1<InputStream> function) {
+ final Function0<InputStream> _function = new Function0<InputStream>() {
+ public InputStream apply() {
+ try {
+ IFile _file = EclipseFileHandle.this.getFile();
+ InputStream _contents = _file.getContents();
+ return _contents;
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+ };
+ IOUtils.<InputStream>tryWith(_function, function);
+ }
+
+ public void writeContents(final Function1<FileHandle,CharSequence> function) {
+ final Procedure1<OutputStream> _function = new Procedure1<OutputStream>() {
+ public void apply(final OutputStream outputStream) {
+ try {
+ CharSequence _apply = function.apply(EclipseFileHandle.this);
+ final OutputSupplier<BufferedWriter> _function = new OutputSupplier<BufferedWriter>() {
+ public BufferedWriter getOutput() throws IOException {
+ OutputStreamWriter _outputStreamWriter = new OutputStreamWriter(outputStream);
+ BufferedWriter _bufferedWriter = new BufferedWriter(_outputStreamWriter);
+ return _bufferedWriter;
+ }
+ };
+ CharStreams.<BufferedWriter>write(_apply, _function);
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+ };
+ this.write(_function);
+ }
+
+ public void write(final Procedure1<OutputStream> function) {
+ final Function0<ByteArrayOutputStream> _function = new Function0<ByteArrayOutputStream>() {
+ public ByteArrayOutputStream apply() {
+ ByteArrayOutputStream _byteArrayOutputStream = new ByteArrayOutputStream();
+ return _byteArrayOutputStream;
+ }
+ };
+ final Procedure1<ByteArrayOutputStream> _function_1 = new Procedure1<ByteArrayOutputStream>() {
+ public void apply(final ByteArrayOutputStream it) {
+ function.apply(it);
+ final Function0<BufferedInputStream> _function = new Function0<BufferedInputStream>() {
+ public BufferedInputStream apply() {
+ byte[] _byteArray = it.toByteArray();
+ ByteArrayInputStream _byteArrayInputStream = new ByteArrayInputStream(_byteArray);
+ BufferedInputStream _bufferedInputStream = new BufferedInputStream(_byteArrayInputStream);
+ return _bufferedInputStream;
+ }
+ };
+ final Procedure1<BufferedInputStream> _function_1 = new Procedure1<BufferedInputStream>() {
+ public void apply(final BufferedInputStream it) {
+ try {
+ IFile _file = EclipseFileHandle.this.getFile();
+ IFile _ensureCreated = EclipseFileHandle.this.ensureCreated(_file);
+ NullProgressMonitor _nullProgressMonitor = new NullProgressMonitor();
+ _ensureCreated.setContents(it, true, true, _nullProgressMonitor);
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+ };
+ IOUtils.<BufferedInputStream>tryWith(_function, _function_1);
+ }
+ };
+ IOUtils.<ByteArrayOutputStream>tryWith(_function, _function_1);
+ }
+
+ protected IFile _ensureCreated(final IFile it) {
+ try {
+ IFile _xblockexpression = null;
+ {
+ boolean _exists = it.exists();
+ boolean _not = (!_exists);
+ if (_not) {
+ IContainer _parent = it.getParent();
+ this.ensureCreated(_parent);
+ byte[] _newByteArrayOfSize = new byte[0];
+ ByteArrayInputStream _byteArrayInputStream = new ByteArrayInputStream(_newByteArrayOfSize);
+ NullProgressMonitor _nullProgressMonitor = new NullProgressMonitor();
+ it.create(_byteArrayInputStream, true, _nullProgressMonitor);
+ }
+ IFile _file = this.getFile();
+ _xblockexpression = (_file);
+ }
+ return _xblockexpression;
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+
+ protected IFile _ensureCreated(final IFolder it) {
+ try {
+ IFile _xblockexpression = null;
+ {
+ boolean _exists = it.exists();
+ boolean _not = (!_exists);
+ if (_not) {
+ IContainer _parent = it.getParent();
+ this.ensureCreated(_parent);
+ NullProgressMonitor _nullProgressMonitor = new NullProgressMonitor();
+ it.create(true, true, _nullProgressMonitor);
+ }
+ _xblockexpression = (null);
+ }
+ return _xblockexpression;
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+
+ protected IFile _ensureCreated(final IContainer it) {
+ IFile _xblockexpression = null;
+ {
+ boolean _exists = it.exists();
+ boolean _not = (!_exists);
+ if (_not) {
+ StringConcatenation _builder = new StringConcatenation();
+ _builder.append("Container does not exist: \'");
+ _builder.append(this.path, "");
+ _builder.append("\'.");
+ IllegalStateException _illegalStateException = new IllegalStateException(_builder.toString());
+ throw _illegalStateException;
+ }
+ _xblockexpression = (null);
+ }
+ return _xblockexpression;
+ }
+
+ public IFile ensureCreated(final IResource it) {
+ if (it instanceof IFile) {
+ return _ensureCreated((IFile)it);
+ } else if (it instanceof IFolder) {
+ return _ensureCreated((IFolder)it);
+ } else if (it instanceof IContainer) {
+ return _ensureCreated((IContainer)it);
+ } else {
+ throw new IllegalArgumentException("Unhandled parameter types: " +
+ Arrays.<Object>asList(it).toString());
+ }
+ }
+}
diff --git a/plugins/org.eclipse.xtend.ide/xtend-gen/org/eclipse/xtend/ide/macro/fsaccess/EclipseFileSystemAccessImpl.java b/plugins/org.eclipse.xtend.ide/xtend-gen/org/eclipse/xtend/ide/macro/fsaccess/EclipseFileSystemAccessImpl.java
new file mode 100644
index 0000000..53ffb8a
--- /dev/null
+++ b/plugins/org.eclipse.xtend.ide/xtend-gen/org/eclipse/xtend/ide/macro/fsaccess/EclipseFileSystemAccessImpl.java
@@ -0,0 +1,185 @@
+package org.eclipse.xtend.ide.macro.fsaccess;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.Iterables;
+import com.google.inject.Inject;
+import java.util.Set;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.xtend.core.macro.declaration.CompilationUnitImpl;
+import org.eclipse.xtend.core.macro.fsaccess.AbstractFileSystemAccessImpl;
+import org.eclipse.xtend.core.xtend.XtendFile;
+import org.eclipse.xtend.ide.macro.fsaccess.EclipseFolderHandle;
+import org.eclipse.xtend.lib.macro.services.FolderHandle;
+import org.eclipse.xtext.builder.EclipseOutputConfigurationProvider;
+import org.eclipse.xtext.common.types.access.jdt.IJavaProjectProvider;
+import org.eclipse.xtext.generator.OutputConfiguration;
+import org.eclipse.xtext.parser.IEncodingProvider;
+import org.eclipse.xtext.ui.resource.IStorage2UriMapper;
+import org.eclipse.xtext.util.Pair;
+import org.eclipse.xtext.xbase.lib.Conversions;
+import org.eclipse.xtext.xbase.lib.Exceptions;
+import org.eclipse.xtext.xbase.lib.Functions.Function1;
+import org.eclipse.xtext.xbase.lib.IterableExtensions;
+
+@SuppressWarnings("all")
+public class EclipseFileSystemAccessImpl extends AbstractFileSystemAccessImpl {
+ @Inject
+ private IStorage2UriMapper mapper;
+
+ @Inject
+ private IEncodingProvider encodingProvider;
+
+ @Inject
+ private IJavaProjectProvider javaProjectProvider;
+
+ @Inject
+ private EclipseOutputConfigurationProvider outputConfigurationProvider;
+
+ public FolderHandle doGetSourceFolder(final CompilationUnitImpl it) {
+ EclipseFolderHandle _xblockexpression = null;
+ {
+ final IFile file = this.getFile(it);
+ boolean _equals = Objects.equal(file, null);
+ if (_equals) {
+ return null;
+ }
+ final IPath sourcePath = this.getSourcePath(it);
+ boolean _equals_1 = Objects.equal(sourcePath, null);
+ if (_equals_1) {
+ return null;
+ }
+ IProject _project = file.getProject();
+ EclipseFolderHandle _eclipseFolderHandle = new EclipseFolderHandle(_project, sourcePath, this.encodingProvider);
+ _xblockexpression = (_eclipseFolderHandle);
+ }
+ return _xblockexpression;
+ }
+
+ public FolderHandle doGetRootFolder(final CompilationUnitImpl it) {
+ EclipseFolderHandle _xblockexpression = null;
+ {
+ final IFile file = this.getFile(it);
+ boolean _equals = Objects.equal(file, null);
+ if (_equals) {
+ return null;
+ }
+ IProject _project = file.getProject();
+ IProject _project_1 = file.getProject();
+ IPath _projectRelativePath = _project_1.getProjectRelativePath();
+ EclipseFolderHandle _eclipseFolderHandle = new EclipseFolderHandle(_project, _projectRelativePath, this.encodingProvider);
+ _xblockexpression = (_eclipseFolderHandle);
+ }
+ return _xblockexpression;
+ }
+
+ public FolderHandle doGetTargetFolder(final CompilationUnitImpl it) {
+ EclipseFolderHandle _xblockexpression = null;
+ {
+ final IFile file = this.getFile(it);
+ boolean _equals = Objects.equal(file, null);
+ if (_equals) {
+ return null;
+ }
+ OutputConfiguration _outputConfig = this.getOutputConfig(file);
+ final String directory = _outputConfig.getOutputDirectory();
+ IPath _sourcePath = this.getSourcePath(it);
+ String _plus = ("../" + directory);
+ final IPath path = _sourcePath.append(_plus);
+ IProject _project = file.getProject();
+ EclipseFolderHandle _eclipseFolderHandle = new EclipseFolderHandle(_project, path, this.encodingProvider);
+ _xblockexpression = (_eclipseFolderHandle);
+ }
+ return _xblockexpression;
+ }
+
+ public IPath getSourcePath(final CompilationUnitImpl it) {
+ try {
+ IPath _xblockexpression = null;
+ {
+ IFile _file = this.getFile(it);
+ IPath _fullPath = null;
+ if (_file!=null) {
+ _fullPath=_file.getFullPath();
+ }
+ final IPath filePath = _fullPath;
+ boolean _equals = Objects.equal(filePath, null);
+ if (_equals) {
+ return null;
+ }
+ IJavaProject _javaProject = this.getJavaProject(it);
+ IClasspathEntry[] _resolvedClasspath = _javaProject.getResolvedClasspath(true);
+ final Function1<IClasspathEntry,Boolean> _function = new Function1<IClasspathEntry,Boolean>() {
+ public Boolean apply(final IClasspathEntry it) {
+ boolean _and = false;
+ int _entryKind = it.getEntryKind();
+ boolean _equals = (_entryKind == IClasspathEntry.CPE_SOURCE);
+ if (!_equals) {
+ _and = false;
+ } else {
+ IPath _path = it.getPath();
+ boolean _isPrefixOf = _path.isPrefixOf(filePath);
+ _and = (_equals && _isPrefixOf);
+ }
+ return Boolean.valueOf(_and);
+ }
+ };
+ Iterable<IClasspathEntry> _filter = IterableExtensions.<IClasspathEntry>filter(((Iterable<IClasspathEntry>)Conversions.doWrapArray(_resolvedClasspath)), _function);
+ IClasspathEntry _head = IterableExtensions.<IClasspathEntry>head(_filter);
+ IPath _path = null;
+ if (_head!=null) {
+ _path=_head.getPath();
+ }
+ IPath _removeFirstSegments = _path.removeFirstSegments(1);
+ _xblockexpression = (_removeFirstSegments);
+ }
+ return _xblockexpression;
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+
+ public OutputConfiguration getOutputConfig(final IFile it) {
+ IProject _project = it.getProject();
+ Set<OutputConfiguration> _outputConfigurations = this.outputConfigurationProvider.getOutputConfigurations(_project);
+ OutputConfiguration _head = IterableExtensions.<OutputConfiguration>head(_outputConfigurations);
+ return _head;
+ }
+
+ public IFile getFile(final CompilationUnitImpl it) {
+ Iterable<Pair<IStorage,IProject>> _storages = this.getStorages(it);
+ final Function1<Pair<IStorage,IProject>,IStorage> _function = new Function1<Pair<IStorage,IProject>,IStorage>() {
+ public IStorage apply(final Pair<IStorage,IProject> it) {
+ IStorage _first = it.getFirst();
+ return _first;
+ }
+ };
+ Iterable<IStorage> _map = IterableExtensions.<Pair<IStorage,IProject>, IStorage>map(_storages, _function);
+ Iterable<IFile> _filter = Iterables.<IFile>filter(_map, IFile.class);
+ IFile _head = IterableExtensions.<IFile>head(_filter);
+ return _head;
+ }
+
+ public Iterable<Pair<IStorage,IProject>> getStorages(final CompilationUnitImpl it) {
+ XtendFile _xtendFile = it.getXtendFile();
+ Resource _eResource = _xtendFile.eResource();
+ URI _uRI = _eResource.getURI();
+ Iterable<Pair<IStorage,IProject>> _storages = this.mapper.getStorages(_uRI);
+ return _storages;
+ }
+
+ public IJavaProject getJavaProject(final CompilationUnitImpl it) {
+ XtendFile _xtendFile = it.getXtendFile();
+ Resource _eResource = _xtendFile.eResource();
+ ResourceSet _resourceSet = _eResource.getResourceSet();
+ IJavaProject _javaProject = this.javaProjectProvider.getJavaProject(_resourceSet);
+ return _javaProject;
+ }
+}
diff --git a/plugins/org.eclipse.xtend.ide/xtend-gen/org/eclipse/xtend/ide/macro/fsaccess/EclipseFolderHandle.java b/plugins/org.eclipse.xtend.ide/xtend-gen/org/eclipse/xtend/ide/macro/fsaccess/EclipseFolderHandle.java
new file mode 100644
index 0000000..2892dd5
--- /dev/null
+++ b/plugins/org.eclipse.xtend.ide/xtend-gen/org/eclipse/xtend/ide/macro/fsaccess/EclipseFolderHandle.java
@@ -0,0 +1,69 @@
+package org.eclipse.xtend.ide.macro.fsaccess;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.xtend.ide.macro.fsaccess.EclipseFileHandle;
+import org.eclipse.xtend.ide.macro.fsaccess.EclipseResourceHandle;
+import org.eclipse.xtend.lib.macro.services.FileHandle;
+import org.eclipse.xtend.lib.macro.services.FolderHandle;
+import org.eclipse.xtend2.lib.StringConcatenation;
+import org.eclipse.xtext.parser.IEncodingProvider;
+
+@SuppressWarnings("all")
+public class EclipseFolderHandle extends EclipseResourceHandle implements FolderHandle {
+ public EclipseFolderHandle(final IProject project, final IPath path, final IEncodingProvider encodingProvider) {
+ super(project, path, encodingProvider);
+ }
+
+ public FileHandle getFile(final String path) {
+ EclipseFileHandle _xblockexpression = null;
+ {
+ final IPath filePath = this.path.append(path);
+ final IFolder folder = this.project.getFolder(filePath);
+ boolean _exists = folder.exists();
+ if (_exists) {
+ StringConcatenation _builder = new StringConcatenation();
+ _builder.append("Given path is an existed folder (not a file): \'");
+ IPath _location = folder.getLocation();
+ IPath _makeAbsolute = _location.makeAbsolute();
+ _builder.append(_makeAbsolute, "");
+ _builder.append("\'.");
+ IllegalStateException _illegalStateException = new IllegalStateException(_builder.toString());
+ throw _illegalStateException;
+ }
+ EclipseFileHandle _eclipseFileHandle = new EclipseFileHandle(this.project, filePath, this.encodingProvider);
+ _xblockexpression = (_eclipseFileHandle);
+ }
+ return _xblockexpression;
+ }
+
+ public FolderHandle getFolder(final String path) {
+ EclipseFolderHandle _xblockexpression = null;
+ {
+ final IPath filePath = this.path.append(path);
+ final IFile file = this.project.getFile(filePath);
+ boolean _exists = file.exists();
+ if (_exists) {
+ StringConcatenation _builder = new StringConcatenation();
+ _builder.append("Given path is an existed file (not a folder): \'");
+ IPath _location = file.getLocation();
+ IPath _makeAbsolute = _location.makeAbsolute();
+ _builder.append(_makeAbsolute, "");
+ _builder.append("\'.");
+ IllegalStateException _illegalStateException = new IllegalStateException(_builder.toString());
+ throw _illegalStateException;
+ }
+ EclipseFolderHandle _eclipseFolderHandle = new EclipseFolderHandle(this.project, filePath, this.encodingProvider);
+ _xblockexpression = (_eclipseFolderHandle);
+ }
+ return _xblockexpression;
+ }
+
+ public IResource getMember() {
+ IFolder _folder = this.getFolder();
+ return _folder;
+ }
+}
diff --git a/plugins/org.eclipse.xtend.ide/xtend-gen/org/eclipse/xtend/ide/macro/fsaccess/EclipseResourceHandle.java b/plugins/org.eclipse.xtend.ide/xtend-gen/org/eclipse/xtend/ide/macro/fsaccess/EclipseResourceHandle.java
new file mode 100644
index 0000000..49ddbf7
--- /dev/null
+++ b/plugins/org.eclipse.xtend.ide/xtend-gen/org/eclipse/xtend/ide/macro/fsaccess/EclipseResourceHandle.java
@@ -0,0 +1,78 @@
+package org.eclipse.xtend.ide.macro.fsaccess;
+
+import com.google.common.base.Objects;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.xtend.lib.macro.services.ResourceHandle;
+import org.eclipse.xtext.parser.IEncodingProvider;
+
+@SuppressWarnings("all")
+public abstract class EclipseResourceHandle implements ResourceHandle {
+ protected final IPath path;
+
+ protected final IProject project;
+
+ protected final IEncodingProvider encodingProvider;
+
+ public EclipseResourceHandle(final IProject project, final IPath path, final IEncodingProvider encodingProvider) {
+ this.project = project;
+ this.path = path;
+ this.encodingProvider = encodingProvider;
+ }
+
+ public boolean exists() {
+ boolean _exists = this.project.exists(this.path);
+ return _exists;
+ }
+
+ public String getName() {
+ IPath _location = this.getLocation();
+ String _lastSegment = _location.lastSegment();
+ return _lastSegment;
+ }
+
+ public String getPath() {
+ IPath _location = this.getLocation();
+ String _string = _location.toString();
+ return _string;
+ }
+
+ public IFile getFile() {
+ IFile _file = this.project.getFile(this.path);
+ return _file;
+ }
+
+ public IFolder getFolder() {
+ IFolder _folder = this.project.getFolder(this.path);
+ return _folder;
+ }
+
+ public IPath getLocation() {
+ IPath _xblockexpression = null;
+ {
+ IResource resource = this.project.findMember(this.path);
+ boolean _equals = Objects.equal(resource, null);
+ if (_equals) {
+ IResource _member = this.getMember();
+ resource = _member;
+ }
+ IPath _location = resource.getLocation();
+ IPath _makeAbsolute = _location.makeAbsolute();
+ _xblockexpression = (_makeAbsolute);
+ }
+ return _xblockexpression;
+ }
+
+ public abstract IResource getMember();
+
+ public String getEncoding() {
+ String _path = this.getPath();
+ URI _createFileURI = URI.createFileURI(_path);
+ String _encoding = this.encodingProvider.getEncoding(_createFileURI);
+ return _encoding;
+ }
+}
diff --git a/plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/TransformationContext.java b/plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/TransformationContext.java
index c345013..1841087 100644
--- a/plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/TransformationContext.java
+++ b/plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/TransformationContext.java
@@ -7,6 +7,7 @@
*******************************************************************************/
package org.eclipse.xtend.lib.macro;
+import org.eclipse.xtend.lib.macro.services.FileSystemAccess;
import org.eclipse.xtend.lib.macro.services.ProblemSupport;
import org.eclipse.xtend.lib.macro.services.Tracability;
import org.eclipse.xtend.lib.macro.services.TypeLookup;
@@ -15,7 +16,7 @@ import org.eclipse.xtend.lib.macro.services.TypeReferenceProvider;
import com.google.common.annotations.Beta;
/**
- * Services provided during transformation phase
+ * Services provided during transformation phase
*
* @author Sven Efftinge
*
@@ -23,6 +24,6 @@ import com.google.common.annotations.Beta;
*/
@Beta
public interface TransformationContext extends Tracability, ProblemSupport,
- TypeReferenceProvider, TypeLookup {
+ TypeReferenceProvider, TypeLookup, FileSystemAccess {
}
diff --git a/plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/services/FileHandle.java b/plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/services/FileHandle.java
new file mode 100644
index 0000000..70ec933
--- /dev/null
+++ b/plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/services/FileHandle.java
@@ -0,0 +1,70 @@
+package org.eclipse.xtend.lib.macro.services;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.eclipse.xtext.xbase.lib.Functions;
+import org.eclipse.xtext.xbase.lib.Procedures;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Representation of a file.
+ *
+ * @author Anton Kosyakov
+ *
+ */
+@Beta
+public interface FileHandle extends ResourceHandle {
+
+ /**
+ * Returns the contents of this file as string.
+ *
+ *
+ * @return the contents of this file as string
+ */
+ String getContents();
+
+ /**
+ * <p>
+ * Opens the input stream on the contents of this file and passes it into
+ * the given function.
+ * </p>
+ * <p>
+ * After invocation of the function this method closes the input stream.
+ * </p>
+ *
+ * @param function
+ * - the function which processes the input stream
+ *
+ */
+ void read(Procedures.Procedure1<InputStream> function);
+
+ /**
+ * <p>
+ * Opens the output stream and writes the contents which is provided by the
+ * given function.
+ * </p>
+ * <p>
+ * After writing of the contents into the file closes the output stream.
+ * </p>
+ *
+ * @param function
+ * - the function which provides the contents as string
+ */
+ void writeContents(Functions.Function1<FileHandle, CharSequence> function);
+
+ /**
+ * <p>
+ * Opens the output stream and passes it into the given function.
+ * </p>
+ * <p>
+ * After invocation of the function closes the output stream.
+ * </p>
+ *
+ * @param function
+ * - the function which processes the output stream
+ */
+ void write(Procedures.Procedure1<OutputStream> function);
+
+}
diff --git a/plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/services/FileSystemAccess.java b/plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/services/FileSystemAccess.java
new file mode 100644
index 0000000..91607ad
--- /dev/null
+++ b/plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/services/FileSystemAccess.java
@@ -0,0 +1,39 @@
+package org.eclipse.xtend.lib.macro.services;
+
+import com.google.common.annotations.Beta;
+
+/**
+ *
+ * Support for accessing the file system.
+ *
+ * @author Anton Kosyakov
+ *
+ */
+@Beta
+public interface FileSystemAccess {
+
+ /**
+ * Returns the root folder handle.
+ *
+ * @return the root folder handle
+ * @see FolderHandle
+ */
+ FolderHandle getRootFolder();
+
+ /**
+ * Returns the source folder handle.
+ *
+ * @return the source folder handle
+ * @see FolderHandle
+ */
+ FolderHandle getSourceFolder();
+
+ /**
+ * Returns the target folder handle.
+ *
+ * @return the target folder handle
+ * @see FolderHandle
+ */
+ FolderHandle getTargetFolder();
+
+}
diff --git a/plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/services/FolderHandle.java b/plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/services/FolderHandle.java
new file mode 100644
index 0000000..ad2b409
--- /dev/null
+++ b/plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/services/FolderHandle.java
@@ -0,0 +1,39 @@
+package org.eclipse.xtend.lib.macro.services;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Representation of a folder.
+ *
+ * @author Anton Kosyakov
+ */
+@Beta
+public interface FolderHandle extends ResourceHandle {
+
+ /**
+ * <p>
+ * Returns {@link FileHandle} for the given path relative to this folder.
+ * </p>
+ *
+ * @param path
+ * - the relative path to the file
+ * @return the file handle for the given path
+ * @exception IllegalStateException
+ * if the resolved resource is a folder (not a file)
+ */
+ FileHandle getFile(String path);
+
+ /**
+ * <p>
+ * Returns {@link FolderHandle} for the given path relative to this folder.
+ * </p>
+ *
+ * @param path
+ * - the relative path to the folder
+ * @return the folder handle for the given path
+ * @exception IllegalStateException
+ * if the resolved resource is a file (not a folder)
+ */
+ FolderHandle getFolder(String path);
+
+}
diff --git a/plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/services/ResourceHandle.java b/plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/services/ResourceHandle.java
new file mode 100644
index 0000000..2befdb3
--- /dev/null
+++ b/plugins/org.eclipse.xtend.lib/src/org/eclipse/xtend/lib/macro/services/ResourceHandle.java
@@ -0,0 +1,36 @@
+package org.eclipse.xtend.lib.macro.services;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * A representation of file system resources.
+ *
+ * @author Anton Kosyakov
+ *
+ */
+@Beta
+public interface ResourceHandle {
+
+ /**
+ * Returns the last segment of the file path.
+ *
+ * @return the last segment of the file path
+ */
+ String getName();
+
+ /**
+ * Returns the canonical path to the file.
+ *
+ * @return the canonical path to the file
+ */
+ String getPath();
+
+ /**
+ * Tests whether this resource exists.
+ *
+ * @return <code>true</code> if this resource exists; otherwise
+ * <code>false</code>
+ */
+ boolean exists();
+
+}
diff --git a/plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/XtendCompile.java b/plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/XtendCompile.java
index 94989b0..7a2475b 100644
--- a/plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/XtendCompile.java
+++ b/plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/XtendCompile.java
@@ -12,10 +12,12 @@ import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.MojoExecutionException;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.xtend.core.compiler.batch.XtendBatchCompiler;
+import org.eclipse.xtend.maven.macro.fsaccess.MavenFileSystemAccessImpl;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
+import com.google.inject.Inject;
/**
* Goal which compiles Xtend sources.
@@ -41,6 +43,9 @@ public class XtendCompile extends AbstractXtendCompilerMojo {
*/
private String tempDirectory;
+ @Inject
+ private MavenFileSystemAccessImpl fileSystemAccess;
+
@Override
protected void internalExecute() throws MojoExecutionException {
final String defaultValue = project.getBasedir() + "/src/main/generated-sources/xtend";
@@ -61,9 +66,11 @@ public class XtendCompile extends AbstractXtendCompilerMojo {
List<String> compileSourceRoots = Lists.newArrayList(project.getCompileSourceRoots());
String classPath = concat(File.pathSeparator, getClassPath());
project.addCompileSourceRoot(outputDirectory);
+ fileSystemAccess.setTargetDirectory(outputDirectory);
compile(xtend2BatchCompiler, classPath, compileSourceRoots, outputDirectory);
}
+ @SuppressWarnings("deprecation")
protected List<String> getClassPath() {
Set<String> classPath = Sets.newLinkedHashSet();
classPath.add(project.getBuild().getSourceDirectory());
diff --git a/plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/XtendMavenModule.java b/plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/XtendMavenModule.java
index 37dfaff..7c308a5 100644
--- a/plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/XtendMavenModule.java
+++ b/plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/XtendMavenModule.java
@@ -1,6 +1,8 @@
package org.eclipse.xtend.maven;
import org.eclipse.xtend.core.XtendRuntimeModule;
+import org.eclipse.xtend.core.macro.fsaccess.FileSystemAccessSPI;
+import org.eclipse.xtend.maven.macro.fsaccess.MavenFileSystemAccessImpl;
import org.eclipse.xtext.generator.trace.ITraceURIConverter;
public class XtendMavenModule extends XtendRuntimeModule {
@@ -8,4 +10,9 @@ public class XtendMavenModule extends XtendRuntimeModule {
public Class<? extends ITraceURIConverter> bindITraceURIConverter() {
return MavenTraceURIConverter.class;
}
+
+ public Class<? extends FileSystemAccessSPI> bindFileSystemAccessPSI() {
+ return MavenFileSystemAccessImpl.class;
+ }
+
}
diff --git a/plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/XtendTestCompile.java b/plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/XtendTestCompile.java
index 7ccb174..85c2a34 100644
--- a/plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/XtendTestCompile.java
+++ b/plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/XtendTestCompile.java
@@ -12,10 +12,12 @@ import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.MojoExecutionException;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.xtend.core.compiler.batch.XtendBatchCompiler;
+import org.eclipse.xtend.maven.macro.fsaccess.MavenFileSystemAccessImpl;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
+import com.google.inject.Inject;
/**
* Goal which compiles Xtend2 test sources.
@@ -41,6 +43,9 @@ public class XtendTestCompile extends AbstractXtendCompilerMojo {
*/
private String testTempDirectory;
+ @Inject
+ private MavenFileSystemAccessImpl fileSystemAccess;
+
@Override
protected void internalExecute() throws MojoExecutionException {
final String defaultValue = project.getBasedir() + "/src/test/generated-sources/xtend";
@@ -61,9 +66,11 @@ public class XtendTestCompile extends AbstractXtendCompilerMojo {
List<String> testCompileSourceRoots = Lists.newArrayList(project.getTestCompileSourceRoots());
String testClassPath = concat(File.pathSeparator, getTestClassPath());
project.addTestCompileSourceRoot(testOutputDirectory);
+ fileSystemAccess.setTargetDirectory(testOutputDirectory);
compile(xtend2BatchCompiler, testClassPath, testCompileSourceRoots, testOutputDirectory);
}
+ @SuppressWarnings("deprecation")
protected List<String> getTestClassPath() {
Set<String> classPath = Sets.newLinkedHashSet();
classPath.add(project.getBuild().getTestSourceDirectory());
diff --git a/plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/macro/fsaccess/MavenFileSystemAccessImpl.java b/plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/macro/fsaccess/MavenFileSystemAccessImpl.java
new file mode 100644
index 0000000..9b66f0f
--- /dev/null
+++ b/plugins/org.eclipse.xtend.maven.plugin/src/main/java/org/eclipse/xtend/maven/macro/fsaccess/MavenFileSystemAccessImpl.java
@@ -0,0 +1,89 @@
+package org.eclipse.xtend.maven.macro.fsaccess;
+
+import java.io.File;
+
+import org.apache.maven.project.MavenProject;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.xtend.core.macro.declaration.CompilationUnitImpl;
+import org.eclipse.xtend.core.macro.fsaccess.AbstractFileSystemAccessImpl;
+import org.eclipse.xtend.core.macro.fsaccess.RuntimeFolderHandle;
+import org.eclipse.xtend.lib.macro.services.FolderHandle;
+import org.eclipse.xtend.maven.MavenProjectAdapter;
+import org.eclipse.xtext.parser.IEncodingProvider;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+@Singleton
+public class MavenFileSystemAccessImpl extends AbstractFileSystemAccessImpl {
+
+ @Inject
+ private IEncodingProvider encodingProvider;
+
+ private String targetDirectory;
+
+ public String getTargetDirectory() {
+ return targetDirectory;
+ }
+
+ public void setTargetDirectory(String targetDirectory) {
+ this.targetDirectory = targetDirectory;
+ }
+
+ public FolderHandle doGetRootFolder(CompilationUnitImpl impl) {
+ MavenProject manenProject = getManenProject(impl);
+ if (manenProject == null) {
+ return null;
+ }
+ return new RuntimeFolderHandle(manenProject.getBasedir(), encodingProvider);
+ }
+
+ public FolderHandle doGetSourceFolder(CompilationUnitImpl impl) {
+ Resource eResource = impl.getXtendFile().eResource();
+ URI uri = eResource.getURI();
+ MavenProject manenProject = MavenProjectAdapter.get(eResource.getResourceSet());
+ if (manenProject == null) {
+ return null;
+ }
+ for (String rootString : manenProject.getCompileSourceRoots()) {
+ if (!rootString.endsWith("/")) {
+ rootString += "/";
+ }
+ URI root = URI.createFileURI(rootString);
+ if (isPrefix(root, uri)) {
+ return new RuntimeFolderHandle(new File(rootString), encodingProvider);
+ }
+ }
+ return null;
+ }
+
+ public FolderHandle doGetTargetFolder(CompilationUnitImpl impl) {
+ if (targetDirectory == null) {
+ return null;
+ }
+ return new RuntimeFolderHandle(new File(targetDirectory), encodingProvider);
+ }
+
+ private boolean isPrefix(URI prefix, URI uri) {
+ if (prefix.scheme() == null || !prefix.scheme().equals(uri.scheme()))
+ return false;
+ String[] prefixSeg = prefix.segments();
+ String[] uriSeg = uri.segments();
+ if (prefixSeg.length == 0 || uriSeg.length == 0)
+ return false;
+ if (!"".equals(prefixSeg[prefixSeg.length - 1])) // this is true when the URI has a trailing slash ("/").
+ return false;
+ if (uriSeg.length < prefixSeg.length - 1)
+ return false;
+ for (int i = 0; i < prefixSeg.length - 1; i++)
+ if (!uriSeg[i].equals(prefixSeg[i]))
+ return false;
+ return true;
+ }
+
+ private MavenProject getManenProject(CompilationUnitImpl impl) {
+ return MavenProjectAdapter.get(impl.getXtendFile().eResource().getResourceSet());
+ }
+
+}
diff --git a/plugins/org.eclipse.xtend.maven.plugin/src/test/java/org/eclipse/xtend/maven/XtendCompilerMojoIT.java b/plugins/org.eclipse.xtend.maven.plugin/src/test/java/org/eclipse/xtend/maven/XtendCompilerMojoIT.java
index ce00023..aa7b878 100644
--- a/plugins/org.eclipse.xtend.maven.plugin/src/test/java/org/eclipse/xtend/maven/XtendCompilerMojoIT.java
+++ b/plugins/org.eclipse.xtend.maven.plugin/src/test/java/org/eclipse/xtend/maven/XtendCompilerMojoIT.java
@@ -2,6 +2,8 @@ package org.eclipse.xtend.maven;
import java.io.File;
import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
import junit.framework.Assert;
@@ -16,6 +18,29 @@ public class XtendCompilerMojoIT {
private static String ROOT = "/it/compile";
@Test
+ public void testFileSystemAccess() throws Exception {
+ deleteFileIfExist("myusercode/UserCode.css");
+ deleteFileIfExist("com/itemis/myusercode/UserCode2.css");
+
+ Verifier annotationVerifier = newVerifier(ROOT + "/filesystemaccess");
+ annotationVerifier.setDebug(true);
+ annotationVerifier.executeGoal("install");
+ annotationVerifier.verifyErrorFreeLog();
+
+ Verifier clientVerifier = newVerifier(ROOT + "/filesystemaccess-client");
+ clientVerifier.setDebug(true);
+ clientVerifier.executeGoal("compile");
+ clientVerifier.verifyErrorFreeLog();
+ }
+
+ private void deleteFileIfExist(String path) throws URISyntaxException {
+ URL userCodeURL = getClass().getResource(ROOT + "/filesystemaccess-client/src/main/java/" + path);
+ if (userCodeURL != null) {
+ new File(userCodeURL.toURI()).delete();
+ }
+ }
+
+ @Test
public void projectWithMultipleSourceDirectories() throws Exception {
verifyErrorFreeLog(ROOT + "/multisources");
}
@@ -28,10 +53,10 @@ public class XtendCompilerMojoIT {
@Test
public void encoding() throws Exception {
Verifier verifier = newVerifier(ROOT + "/encoding");
-
+
String xtendDir = verifier.getBasedir() + "/src/main/java";
assertFileContainsUTF16(verifier, xtendDir + "/test/XtendA.xtend", "Mühlheim-Kärlicher Bürger");
-
+
verifier.setDebug(true);
verifier.executeGoal("test");
verifier.verifyErrorFreeLog();
diff --git a/plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess-client/pom.xml b/plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess-client/pom.xml
new file mode 100644
index 0000000..d34b11d
--- /dev/null
+++ b/plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess-client/pom.xml
@@ -0,0 +1,36 @@
+<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/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>filesystemaccess-client</artifactId>
+ <version>IT-SNAPSHOT</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>xtend-maven-plugin</artifactId>
+ <version>IT-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>org.eclipse.xtend.lib</artifactId>
+ <version>[2.4,)</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>filesystemaccess</artifactId>
+ <version>IT-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess-client/src/main/.gitignore b/plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess-client/src/main/.gitignore
new file mode 100644
index 0000000..acab442
--- /dev/null
+++ b/plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess-client/src/main/.gitignore
@@ -0,0 +1 @@
+/generated-sources
diff --git a/plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess-client/src/main/java/myusercode/UserCode.xtend b/plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess-client/src/main/java/myusercode/UserCode.xtend
new file mode 100644
index 0000000..a088100
--- /dev/null
+++ b/plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess-client/src/main/java/myusercode/UserCode.xtend
@@ -0,0 +1,5 @@
+package myusercode
+
+@myannotation.MyAnnotation
+class MyClass {
+}
diff --git a/plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess/pom.xml b/plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess/pom.xml
new file mode 100644
index 0000000..b6d53b1
--- /dev/null
+++ b/plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess/pom.xml
@@ -0,0 +1,41 @@
+<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/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>filesystemaccess</artifactId>
+ <version>IT-SNAPSHOT</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>xtend-maven-plugin</artifactId>
+ <version>IT-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>org.eclipse.xtend.lib</artifactId>
+ <version>[2.4,)</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>org.eclipse.xtend.standalone</artifactId>
+ <version>[2.4,)</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.8.1</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess/src/main/java/myannotation/MyAnnotation.xtend b/plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess/src/main/java/myannotation/MyAnnotation.xtend
new file mode 100644
index 0000000..b71fb3b
--- /dev/null
+++ b/plugins/org.eclipse.xtend.maven.plugin/src/test/resources/it/compile/filesystemaccess/src/main/java/myannotation/MyAnnotation.xtend
@@ -0,0 +1,107 @@
+package myannotation
+
+import com.google.common.io.CharStreams
+import java.io.BufferedWriter
+import java.io.InputStreamReader
+import java.io.OutputStreamWriter
+import org.eclipse.xtend.lib.macro.AbstractClassProcessor
+import org.eclipse.xtend.lib.macro.Active
+import org.eclipse.xtend.lib.macro.TransformationContext
+import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration
+
+import static org.eclipse.xtend.core.macro.fsaccess.IOUtils.*
+import static org.junit.Assert.*
+
+@Active(typeof(MyAnnotationProcessor))
+annotation MyAnnotation {
+}
+
+class MyAnnotationProcessor extends AbstractClassProcessor {
+
+ override doTransform(MutableClassDeclaration clazz, extension TransformationContext context) {
+ assertNotNull(sourceFolder)
+ assertTrue(sourceFolder.exists)
+ assertEquals("java", sourceFolder.name)
+ assertTrue(sourceFolder.path.endsWith("/it/compile/filesystemaccess-client/src/main/java"))
+
+ assertNotNull(targetFolder)
+ assertTrue(targetFolder.exists)
+ assertEquals("xtend", targetFolder.name)
+ assertTrue(targetFolder.path.endsWith("/it/compile/filesystemaccess-client/src/main/generated-sources/xtend"))
+
+ assertNotNull(rootFolder)
+ assertTrue(rootFolder.exists)
+ assertEquals("filesystemaccess-client", rootFolder.name)
+ assertTrue(rootFolder.path.endsWith("/it/compile/filesystemaccess-client"))
+
+ val myusercodeFolder = sourceFolder.getFolder("myusercode")
+ assertNotNull(myusercodeFolder)
+ assertTrue(myusercodeFolder.exists)
+ assertEquals("myusercode", myusercodeFolder.name)
+ assertTrue(myusercodeFolder.path.endsWith("/it/compile/filesystemaccess-client/src/main/java/myusercode"))
+
+ try {
+ sourceFolder.getFolder("myusercode/UserCode.xtend")
+ fail
+ } catch (IllegalStateException e) {
+ assertTrue(e.message.contains("/it/compile/filesystemaccess-client/src/main/java/myusercode/UserCode.xtend"))
+ }
+
+ val userCodeFile = sourceFolder.getFile("myusercode/UserCode.xtend")
+ assertNotNull(userCodeFile)
+ assertTrue(userCodeFile.exists)
+ assertEquals("UserCode.xtend", userCodeFile.name)
+ assertTrue(
+ userCodeFile.path.endsWith("/it/compile/filesystemaccess-client/src/main/java/myusercode/UserCode.xtend"))
+
+ try {
+ sourceFolder.getFile("myusercode")
+ fail
+ } catch (IllegalStateException e) {
+ assertTrue(e.message.contains("/it/compile/filesystemaccess-client/src/main/java/myusercode"))
+ }
+
+ val userCodeContent = '''
+ package myusercode
+
+ @myannotation.MyAnnotation
+ class MyClass {
+ }
+ '''
+ assertEquals(userCodeContent, userCodeFile.contents)
+ userCodeFile.read[assertEquals(userCodeContent, CharStreams.toString(new InputStreamReader(it)))]
+
+ val userCodeCss = sourceFolder.getFile("myusercode/UserCode.css")
+ assertNotNull(userCodeCss)
+ assertFalse(userCodeCss.exists)
+ assertEquals("UserCode.css", userCodeCss.name)
+ assertTrue(
+ userCodeCss.path.endsWith("/it/compile/filesystemaccess-client/src/main/java/myusercode/UserCode.css"))
+ val helloWorldCssClassDeclaration = ".helloWorldCssClass {}"
+ userCodeCss.writeContents [helloWorldCssClassDeclaration as CharSequence]
+
+ val userCodeCss2 = sourceFolder.getFile("myusercode/UserCode.css")
+ assertNotNull(userCodeCss2)
+ assertTrue(userCodeCss2.exists)
+ assertEquals(helloWorldCssClassDeclaration, userCodeCss2.contents)
+
+ val userCode2Css = sourceFolder.getFile("com/itemis/myusercode/UserCode2.css")
+ assertNotNull(userCode2Css)
+ assertFalse(userCode2Css.exists)
+ assertEquals("UserCode2.css", userCode2Css.name)
+ assertTrue(
+ userCode2Css.path.endsWith(
+ "/it/compile/filesystemaccess-client/src/main/java/com/itemis/myusercode/UserCode2.css"))
+ userCode2Css.write [
+ tryWith([|new BufferedWriter(new OutputStreamWriter(it))]) [
+ write(helloWorldCssClassDeclaration)
+ ]
+ ]
+
+ val userCode2Css2 = sourceFolder.getFile("com/itemis/myusercode/UserCode2.css")
+ assertNotNull(userCode2Css2)
+ assertTrue(userCode2Css2.exists)
+ assertEquals(helloWorldCssClassDeclaration, userCode2Css2.contents)
+ }
+
+}
diff --git a/tests/org.eclipse.xtend.core.tests/src/org/eclipse/xtend/core/tests/macro/ActiveAnnotationsRuntimeTest.xtend b/tests/org.eclipse.xtend.core.tests/src/org/eclipse/xtend/core/tests/macro/ActiveAnnotationsRuntimeTest.xtend
index fdf8949..1fe9edb 100644
--- a/tests/org.eclipse.xtend.core.tests/src/org/eclipse/xtend/core/tests/macro/ActiveAnnotationsRuntimeTest.xtend
+++ b/tests/org.eclipse.xtend.core.tests/src/org/eclipse/xtend/core/tests/macro/ActiveAnnotationsRuntimeTest.xtend
@@ -3,12 +3,14 @@ package org.eclipse.xtend.core.tests.macro
import com.google.common.collect.Lists
import com.google.inject.Inject
import com.google.inject.Provider
+import org.eclipse.xtend.core.macro.ProcessorInstanceForJvmTypeProvider
import org.eclipse.xtend.core.macro.declaration.CompilationUnitImpl
import org.eclipse.xtend.core.tests.RuntimeInjectorProvider
import org.eclipse.xtend.core.xtend.XtendFile
import org.eclipse.xtend.lib.macro.declaration.MutableTypeDeclaration
import org.eclipse.xtext.junit4.InjectWith
import org.eclipse.xtext.junit4.XtextRunner
+import org.eclipse.xtext.junit4.validation.ValidationTestHelper
import org.eclipse.xtext.resource.XtextResourceSet
import org.eclipse.xtext.xbase.compiler.CompilationTestHelper
import org.eclipse.xtext.xbase.lib.IterableExtensions
@@ -16,35 +18,33 @@ import org.eclipse.xtext.xbase.lib.Pair
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.eclipse.xtend.core.macro.ProcessorInstanceForJvmTypeProvider
import static org.junit.Assert.*
-import org.eclipse.xtext.junit4.validation.ValidationTestHelper
@RunWith(typeof(XtextRunner))
@InjectWith(typeof(RuntimeInjectorProvider))
class ActiveAnnotationsRuntimeTest extends AbstractReusableActiveAnnotationTests {
-
+
@Inject CompilationTestHelper compiler
@Inject Provider<CompilationUnitImpl> compilationUnitProvider
@Inject ProcessorInstanceForJvmTypeProvider processorProvider
@Inject ValidationTestHelper validationTestHelper
-
+
@Before
def void setUp() {
- compiler.setJavaCompilerClassPath(typeof(MutableTypeDeclaration) , typeof(IterableExtensions), typeof(Lists))
+ compiler.setJavaCompilerClassPath(typeof(MutableTypeDeclaration), typeof(IterableExtensions), typeof(Lists))
}
-
- override assertProcessing(Pair<String,String> macroFile, Pair<String,String> clientFile, (CompilationUnitImpl)=>void expectations) {
+
+ override assertProcessing(Pair<String, String> macroFile, Pair<String, String> clientFile,
+ (CompilationUnitImpl)=>void expectations) {
val macroResourceSet = compiler.unLoadedResourceSet(macroFile) as XtextResourceSet
macroResourceSet.classpathURIContext = getClass.classLoader
val resourceSet = compiler.unLoadedResourceSet(clientFile) as XtextResourceSet
compiler.compile(macroResourceSet) [ result |
- val classLoader = new DelegatingClassloader(getClass().classLoader) [result.getCompiledClass(it)]
- resourceSet.classpathURIContext = classLoader
+ val classLoader = new DelegatingClassloader(getClass().classLoader) [result.getCompiledClass(it)]resourceSet.classpathURIContext = classLoader
processorProvider.classLoader = classLoader
]
-
+
val singleResource = resourceSet.resources.head
compiler.compile(resourceSet) [
val unit = compilationUnitProvider.get
@@ -55,31 +55,31 @@ class ActiveAnnotationsRuntimeTest extends AbstractReusableActiveAnnotationTests
assertTrue(singleResource.errors.isEmpty)
]
}
-
+
// dummy override to enable launch configs
@Test override testSimpleModification() {
super.testSimpleModification()
}
-
+
}
class DelegatingClassloader extends ClassLoader {
(String)=>Class<?> classFinder
-
+
new(ClassLoader parent, (String)=>Class<?> classFinder) {
super(parent)
this.classFinder = classFinder
}
-
+
override findClass(String name) throws ClassNotFoundException {
val result = classFinder.apply(name)
if (result != null)
return result
super.findClass(name)
}
-
+
override loadClass(String name) throws ClassNotFoundException {
super.loadClass(name)
}
-
-} \ No newline at end of file
+
+}
diff --git a/tests/org.eclipse.xtend.ide.tests/src/org/eclipse/xtend/ide/tests/macros/ActiveAnnotationsProcessingInIDETest.xtend b/tests/org.eclipse.xtend.ide.tests/src/org/eclipse/xtend/ide/tests/macros/ActiveAnnotationsProcessingInIDETest.xtend
index 991194d..682fbe5 100644
--- a/tests/org.eclipse.xtend.ide.tests/src/org/eclipse/xtend/ide/tests/macros/ActiveAnnotationsProcessingInIDETest.xtend
+++ b/tests/org.eclipse.xtend.ide.tests/src/org/eclipse/xtend/ide/tests/macros/ActiveAnnotationsProcessingInIDETest.xtend
@@ -1,10 +1,14 @@
package org.eclipse.xtend.ide.tests.macros
+import com.google.common.io.CharStreams
import com.google.inject.Inject
import com.google.inject.Provider
import java.io.BufferedInputStream
+import java.io.BufferedWriter
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
+import java.io.InputStreamReader
+import java.io.OutputStreamWriter
import java.util.jar.Manifest
import org.eclipse.core.resources.IFile
import org.eclipse.core.resources.IFolder
@@ -12,87 +16,304 @@ import org.eclipse.emf.common.util.URI
import org.eclipse.jdt.core.IJavaProject
import org.eclipse.jdt.core.JavaCore
import org.eclipse.xtend.core.macro.declaration.CompilationUnitImpl
+import org.eclipse.xtend.core.tests.macro.AbstractReusableActiveAnnotationTests
+import org.eclipse.xtend.core.xtend.XtendClass
+import org.eclipse.xtend.core.xtend.XtendConstructor
+import org.eclipse.xtend.core.xtend.XtendField
import org.eclipse.xtend.core.xtend.XtendFile
+import org.eclipse.xtend.core.xtend.XtendFunction
import org.eclipse.xtend.ide.tests.XtendIDEInjectorProvider
import org.eclipse.xtext.junit4.InjectWith
import org.eclipse.xtext.junit4.XtextRunner
import org.eclipse.xtext.junit4.internal.StopwatchRule
+import org.eclipse.xtext.ui.editor.hover.html.IEObjectHoverDocumentationProvider
import org.eclipse.xtext.ui.resource.XtextResourceSetProvider
import org.eclipse.xtext.util.StringInputStream
import org.eclipse.xtext.xbase.lib.Pair
import org.junit.After
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import static org.eclipse.xtend.core.macro.fsaccess.IOUtils.*
import static org.eclipse.xtend.ide.tests.WorkbenchTestHelper.*
import static org.eclipse.xtext.junit4.ui.util.IResourcesSetupUtil.*
-import org.eclipse.xtend.core.tests.macro.AbstractReusableActiveAnnotationTests
+import static org.junit.Assert.*
@RunWith(typeof(XtextRunner))
@InjectWith(typeof(XtendIDEInjectorProvider))
class ActiveAnnotationsProcessingInIDETest extends AbstractReusableActiveAnnotationTests {
-
+
+ @Inject
+ private extension IEObjectHoverDocumentationProvider documentationProvider
+
// dummy override, to make launch config available
@Test override testSimpleModification() {
super.testSimpleModification()
}
-
+
+ @Test
+ @Ignore
+ def void testDocumetationProvider() {
+ assertProcessing(
+ 'annotation/ChangeDoc.xtend' -> '''
+ package annotation
+
+ import java.util.List
+ import org.eclipse.xtend.lib.macro.Active
+ import org.eclipse.xtend.lib.macro.RegisterGlobalsContext
+ import org.eclipse.xtend.lib.macro.RegisterGlobalsParticipant
+ import org.eclipse.xtend.lib.macro.TransformationContext
+ import org.eclipse.xtend.lib.macro.TransformationParticipant
+ import org.eclipse.xtend.lib.macro.declaration.MemberDeclaration
+ import org.eclipse.xtend.lib.macro.declaration.MutableMemberDeclaration
+
+ @Active(ChangeDocProcessor)
+ annotation ChangeDoc {
+ }
+
+ class ChangeDocProcessor implements RegisterGlobalsParticipant<MemberDeclaration>, TransformationParticipant<MutableMemberDeclaration> {
+
+ override doRegisterGlobals(List<? extends MemberDeclaration> annotatedSourceElements, RegisterGlobalsContext context) {
+ //do nothing
+ }
+
+ override doTransform(List<? extends MutableMemberDeclaration> annotatedTargetElements,
+ extension TransformationContext context) {
+ for (it : annotatedTargetElements) {
+ docComment = "Hello World!"
+ }
+ }
+
+ }
+ ''',
+ 'usercode/UserCode.xtend' -> '''
+ package usercode
+
+ import annotation.ChangeDoc
+
+ /**
+ * Comment
+ */
+ @ChangeDoc
+ class UserClass {
+
+ /**
+ * Comment
+ */
+ @ChangeDoc
+ private Object object
+
+ /**
+ * Comment
+ */
+ private Object object2
+
+ /**
+ * Comment
+ */
+ @ChangeDoc
+ new() {
+ this(new Object, new Object)
+ }
+
+ /**
+ * Comment
+ */
+ new(Object object, Object object2) {
+ this.object = object
+ this.object2 = object2
+ }
+
+ /**
+ * Comment
+ */
+ @ChangeDoc
+ def op() {
+ }
+
+ /**
+ * Comment
+ */
+ def op2() {
+ }
+
+ }
+ ''') [
+ val xtendClass = xtendFile.xtendTypes.filter(XtendClass).head
+ assertEquals(
+ '''@<a href="eclipse-xtext-doc:platform:/resource/macroProject/src/annotation/ChangeDoc.xtend%23/1">ChangeDoc</a><br>Hello World!'''.
+ toString, xtendClass.documentation)
+ val objectField = xtendClass.members.filter(XtendField).filter[name.equals("object")].head
+ assertEquals(
+ '''@<a href="eclipse-xtext-doc:platform:/resource/macroProject/src/annotation/ChangeDoc.xtend%23/1">ChangeDoc</a><br>Hello World!'''.
+ toString, objectField.documentation)
+ val objectField2 = xtendClass.members.filter(XtendField).filter[name.equals("object2")].head
+ assertEquals('''Comment'''.toString, objectField2.documentation)
+ val constructor = xtendClass.members.filter(XtendConstructor).filter[parameters.empty].head
+ assertEquals(
+ '''@<a href="eclipse-xtext-doc:platform:/resource/macroProject/src/annotation/ChangeDoc.xtend%23/1">ChangeDoc</a><br>Hello World!'''.
+ toString, constructor.documentation)
+ val constructor2 = xtendClass.members.filter(XtendConstructor).filter[parameters.size == 2].head
+ assertEquals(
+ '''Comment<dl><dt>Parameters:</dt><dd><b>object</b> </dd><dd><b>object2</b> </dd></dl>'''.toString,
+ constructor2.documentation)
+ val opFunction = xtendClass.members.filter(XtendFunction).filter[name.equals("op")].head
+ assertEquals(
+ '''@<a href="eclipse-xtext-doc:platform:/resource/macroProject/src/annotation/ChangeDoc.xtend%23/1">ChangeDoc</a><br>Hello World!'''.
+ toString, opFunction.documentation)
+ val op2Function = xtendClass.members.filter(XtendFunction).filter[name.equals("op2")].head
+ assertEquals('''Comment'''.toString, op2Function.documentation)
+ ]
+ }
+
+ @Test def void testFileSystemAccess() {
+ val userCodeContent = '''
+ package myusercode
+
+ @myannotation.MyAnnotation
+ class MyClass {
+ }
+ '''
+ assertProcessing(
+ 'myannotation/MyAnnotation.xtend' -> '''
+ package myannotation
+
+ import org.eclipse.xtend.lib.macro.Active
+ import org.eclipse.xtend.lib.macro.TransformationContext
+ import org.eclipse.xtend.lib.macro.AbstractClassProcessor
+ import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration
+
+ @Active(typeof(MyAnnotationProcessor))
+ annotation MyAnnotation{ }
+ class MyAnnotationProcessor extends AbstractClassProcessor {
+
+ override doTransform(MutableClassDeclaration clazz, extension TransformationContext context) {
+ }
+
+ }
+ ''',
+ 'myusercode/UserCode.xtend' -> userCodeContent
+ ) [
+ assertNotNull(sourceFolder)
+ assertTrue(sourceFolder.exists)
+ assertEquals("src", sourceFolder.name)
+ assertTrue(sourceFolder.path.endsWith("/userProject/src"))
+ assertNotNull(targetFolder)
+ assertTrue(targetFolder.exists)
+ assertEquals("xtend-gen", targetFolder.name)
+ assertTrue(targetFolder.path.endsWith("/userProject/xtend-gen"))
+ assertNotNull(rootFolder)
+ assertTrue(rootFolder.exists)
+ assertEquals("userProject", rootFolder.name)
+ assertTrue(rootFolder.path.endsWith("/userProject"))
+ val myusercodeFolder = sourceFolder.getFolder("myusercode")
+ assertNotNull(myusercodeFolder)
+ assertTrue(myusercodeFolder.exists)
+ assertEquals("myusercode", myusercodeFolder.name)
+ assertTrue(myusercodeFolder.path.endsWith("/userProject/src/myusercode"))
+ try {
+ sourceFolder.getFolder("myusercode/UserCode.xtend")
+ fail
+ } catch (IllegalStateException e) {
+ assertTrue(e.message.contains("/userProject/src/myusercode/UserCode.xtend"))
+ }
+ val userCodeFile = sourceFolder.getFile("myusercode/UserCode.xtend")
+ assertNotNull(userCodeFile)
+ assertTrue(userCodeFile.exists)
+ assertEquals("UserCode.xtend", userCodeFile.name)
+ assertTrue(userCodeFile.path.endsWith("/userProject/src/myusercode/UserCode.xtend"))
+ try {
+ sourceFolder.getFile("myusercode")
+ fail
+ } catch (IllegalStateException e) {
+ assertTrue(e.message.contains("/userProject/src/myusercode"))
+ }
+ assertEquals(userCodeContent, userCodeFile.contents)
+ userCodeFile.read[assertEquals(userCodeContent, CharStreams.toString(new InputStreamReader(it)))]
+ val userCodeCss = sourceFolder.getFile("myusercode/UserCode.css")
+ assertNotNull(userCodeCss)
+ assertFalse(userCodeCss.exists)
+ assertEquals("UserCode.css", userCodeCss.name)
+ assertTrue(userCodeCss.path.endsWith("/userProject/src/myusercode/UserCode.css"))
+ val helloWorldCssClassDeclaration = ".helloWorldCssClass {}"
+ userCodeCss.writeContents[helloWorldCssClassDeclaration as CharSequence]
+ val userCodeCss2 = sourceFolder.getFile("myusercode/UserCode.css")
+ assertNotNull(userCodeCss2)
+ assertTrue(userCodeCss2.exists)
+ assertEquals(helloWorldCssClassDeclaration, userCodeCss2.contents)
+ val userCode2Css = sourceFolder.getFile("com/itemis/myusercode/UserCode2.css")
+ assertNotNull(userCode2Css)
+ assertFalse(userCode2Css.exists)
+ assertEquals("UserCode2.css", userCode2Css.name)
+ assertTrue(userCode2Css.path.endsWith("/userProject/src/com/itemis/myusercode/UserCode2.css"))
+ userCode2Css.write [
+ tryWith([|new BufferedWriter(new OutputStreamWriter(it))]) [
+ write(helloWorldCssClassDeclaration)
+ ]
+ ]
+ val userCode2Css2 = sourceFolder.getFile("com/itemis/myusercode/UserCode2.css")
+ assertNotNull(userCode2Css2)
+ assertTrue(userCode2Css2.exists)
+ assertEquals(helloWorldCssClassDeclaration, userCode2Css2.contents)
+ ]
+ }
+
@Inject XtextResourceSetProvider resourceSetProvider
- @Inject Provider<CompilationUnitImpl> compilationUnitProvider
+ @Inject Provider<CompilationUnitImpl> compilationUnitProvider
@Rule public StopwatchRule stopwatch = new StopwatchRule(true);
-
+
@After def tearDown() throws Exception {
macroProject = null
userProject = null
sourceFile = null
cleanWorkspace();
}
-
+
IJavaProject macroProject
IJavaProject userProject
IFile sourceFile
-
- override assertProcessing(Pair<String,String> macroFile, Pair<String,String> clientFile, (CompilationUnitImpl)=>void expectations) {
- macroProject = JavaCore::create(createPluginProject("macroProject"))
+
+ override assertProcessing(Pair<String, String> macroFile, Pair<String, String> clientFile,
+ (CompilationUnitImpl)=>void expectations) {
+ macroProject = JavaCore::create(createPluginProject("macroProject"))
macroProject.newSource(macroFile.key, macroFile.value.toString)
val lidx = macroFile.key.lastIndexOf('/')
if (lidx != -1) {
- val packageName = macroFile.key.substring(0, lidx).replace('/','.')
+ val packageName = macroFile.key.substring(0, lidx).replace('/', '.')
macroProject.addExportedPackage(packageName)
}
- userProject = JavaCore::create(createPluginProject("userProject", "com.google.inject",
- "org.eclipse.xtend.lib",
- "org.eclipse.xtext.xbase.lib",
- "org.eclipse.xtend.ide.tests.data",
- "org.junit4", "macroProject"))
+ userProject = JavaCore::create(
+ createPluginProject("userProject", "com.google.inject", "org.eclipse.xtend.lib",
+ "org.eclipse.xtext.xbase.lib", "org.eclipse.xtend.ide.tests.data", "org.junit4", "macroProject"))
sourceFile = userProject.newSource(clientFile.key, clientFile.value.toString)
waitForAutoBuild()
-
+
val resourceSet = resourceSetProvider.get(userProject.project)
val resource = resourceSet.getResource(URI::createPlatformResourceURI(sourceFile.fullPath.toString, true), true)
- val unit = compilationUnitProvider.get
+ val unit = compilationUnitProvider.get
unit.xtendFile = resource.contents.filter(typeof(XtendFile)).head
expectations.apply(unit)
}
-
+
def IFile newSource(IJavaProject it, String fileName, String contents) {
- val result = it.project.getFile("src/"+fileName)
+ val result = it.project.getFile("src/" + fileName)
var parent = result.parent
while (!parent.exists) {
- (parent as IFolder).create(true,false,null)
+ (parent as IFolder).create(true, false, null)
}
result.create(new StringInputStream(contents), true, null)
return result
}
-
+
def void addExportedPackage(IJavaProject pluginProject, String ... exportedPackages) {
val manifestFile = pluginProject.project.getFile("META-INF/MANIFEST.MF")
val manifest = new Manifest(manifestFile.contents)
val attrs = manifest.getMainAttributes()
if (attrs.containsKey("Export-Package")) {
- attrs.putValue("Export-Package", attrs.get("Export-Package")+","+exportedPackages.join(","))
+ attrs.putValue("Export-Package", attrs.get("Export-Package") + "," + exportedPackages.join(","))
} else {
attrs.putValue("Export-Package", exportedPackages.join(","))
}
@@ -101,5 +322,5 @@ class ActiveAnnotationsProcessingInIDETest extends AbstractReusableActiveAnnotat
val in = new ByteArrayInputStream(out.toByteArray)
manifestFile.setContents(new BufferedInputStream(in), true, true, null)
}
-
+
}
diff --git a/tests/org.eclipse.xtend.ide.tests/xtend-gen/org/eclipse/xtend/ide/tests/macros/ActiveAnnotationsProcessingInIDETest.java b/tests/org.eclipse.xtend.ide.tests/xtend-gen/org/eclipse/xtend/ide/tests/macros/ActiveAnnotationsProcessingInIDETest.java
index a62f966..3bfcb6d 100644
--- a/tests/org.eclipse.xtend.ide.tests/xtend-gen/org/eclipse/xtend/ide/tests/macros/ActiveAnnotationsProcessingInIDETest.java
+++ b/tests/org.eclipse.xtend.ide.tests/xtend-gen/org/eclipse/xtend/ide/tests/macros/ActiveAnnotationsProcessingInIDETest.java
@@ -1,12 +1,17 @@
package org.eclipse.xtend.ide.tests.macros;
import com.google.common.collect.Iterables;
+import com.google.common.io.CharStreams;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.io.BufferedInputStream;
+import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import org.eclipse.core.resources.IContainer;
@@ -22,23 +27,39 @@ import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.xtend.core.macro.declaration.CompilationUnitImpl;
+import org.eclipse.xtend.core.macro.fsaccess.IOUtils;
import org.eclipse.xtend.core.tests.macro.AbstractReusableActiveAnnotationTests;
+import org.eclipse.xtend.core.xtend.XtendClass;
+import org.eclipse.xtend.core.xtend.XtendConstructor;
+import org.eclipse.xtend.core.xtend.XtendField;
import org.eclipse.xtend.core.xtend.XtendFile;
+import org.eclipse.xtend.core.xtend.XtendFunction;
+import org.eclipse.xtend.core.xtend.XtendMember;
+import org.eclipse.xtend.core.xtend.XtendParameter;
+import org.eclipse.xtend.core.xtend.XtendTypeDeclaration;
import org.eclipse.xtend.ide.tests.WorkbenchTestHelper;
import org.eclipse.xtend.ide.tests.XtendIDEInjectorProvider;
+import org.eclipse.xtend.lib.macro.services.FileHandle;
+import org.eclipse.xtend.lib.macro.services.FolderHandle;
+import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.junit4.InjectWith;
import org.eclipse.xtext.junit4.XtextRunner;
import org.eclipse.xtext.junit4.internal.StopwatchRule;
import org.eclipse.xtext.junit4.ui.util.IResourcesSetupUtil;
+import org.eclipse.xtext.ui.editor.hover.html.IEObjectHoverDocumentationProvider;
import org.eclipse.xtext.ui.resource.XtextResourceSetProvider;
import org.eclipse.xtext.util.StringInputStream;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Exceptions;
+import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function0;
+import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.Pair;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.junit.After;
+import org.junit.Assert;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -47,11 +68,539 @@ import org.junit.runner.RunWith;
@InjectWith(XtendIDEInjectorProvider.class)
@SuppressWarnings("all")
public class ActiveAnnotationsProcessingInIDETest extends AbstractReusableActiveAnnotationTests {
+ @Inject
+ @Extension
+ private IEObjectHoverDocumentationProvider documentationProvider;
+
@Test
public void testSimpleModification() {
super.testSimpleModification();
}
+ @Test
+ @Ignore
+ public void testDocumetationProvider() {
+ StringConcatenation _builder = new StringConcatenation();
+ _builder.append("package annotation");
+ _builder.newLine();
+ _builder.newLine();
+ _builder.append("import java.util.List");
+ _builder.newLine();
+ _builder.append("import org.eclipse.xtend.lib.macro.Active");
+ _builder.newLine();
+ _builder.append("import org.eclipse.xtend.lib.macro.RegisterGlobalsContext");
+ _builder.newLine();
+ _builder.append("import org.eclipse.xtend.lib.macro.RegisterGlobalsParticipant");
+ _builder.newLine();
+ _builder.append("import org.eclipse.xtend.lib.macro.TransformationContext");
+ _builder.newLine();
+ _builder.append("import org.eclipse.xtend.lib.macro.TransformationParticipant");
+ _builder.newLine();
+ _builder.append("import org.eclipse.xtend.lib.macro.declaration.MemberDeclaration");
+ _builder.newLine();
+ _builder.append("import org.eclipse.xtend.lib.macro.declaration.MutableMemberDeclaration");
+ _builder.newLine();
+ _builder.newLine();
+ _builder.append("@Active(ChangeDocProcessor)");
+ _builder.newLine();
+ _builder.append("annotation ChangeDoc {");
+ _builder.newLine();
+ _builder.append("}");
+ _builder.newLine();
+ _builder.newLine();
+ _builder.append("class ChangeDocProcessor implements RegisterGlobalsParticipant<MemberDeclaration>, TransformationParticipant<MutableMemberDeclaration> {");
+ _builder.newLine();
+ _builder.newLine();
+ _builder.append("\t");
+ _builder.append("override doRegisterGlobals(List<? extends MemberDeclaration> annotatedSourceElements, RegisterGlobalsContext context) {");
+ _builder.newLine();
+ _builder.append("\t\t");
+ _builder.append("//do nothing");
+ _builder.newLine();
+ _builder.append("\t");
+ _builder.append("}");
+ _builder.newLine();
+ _builder.newLine();
+ _builder.append("\t");
+ _builder.append("override doTransform(List<? extends MutableMemberDeclaration> annotatedTargetElements,");
+ _builder.newLine();
+ _builder.append("\t\t");
+ _builder.append("extension TransformationContext context) {");
+ _builder.newLine();
+ _builder.append("\t\t");
+ _builder.append("for (it : annotatedTargetElements) {");
+ _builder.newLine();
+ _builder.append("\t\t\t");
+ _builder.append("docComment = \"Hello World!\"");
+ _builder.newLine();
+ _builder.append("\t\t");
+ _builder.append("}");
+ _builder.newLine();
+ _builder.append("\t");
+ _builder.append("}");
+ _builder.newLine();
+ _builder.newLine();
+ _builder.append("}");
+ _builder.newLine();
+ Pair<String,String> _mappedTo = Pair.<String, String>of("annotation/ChangeDoc.xtend", _builder.toString());
+ StringConcatenation _builder_1 = new StringConcatenation();
+ _builder_1.append("package usercode");
+ _builder_1.newLine();
+ _builder_1.newLine();
+ _builder_1.append("import annotation.ChangeDoc");
+ _builder_1.newLine();
+ _builder_1.newLine();
+ _builder_1.append("/** ");
+ _builder_1.newLine();
+ _builder_1.append(" ");
+ _builder_1.append("*\t Comment");
+ _builder_1.newLine();
+ _builder_1.append(" ");
+ _builder_1.append("*/");
+ _builder_1.newLine();
+ _builder_1.append("@ChangeDoc");
+ _builder_1.newLine();
+ _builder_1.append("class UserClass {");
+ _builder_1.newLine();
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("/** ");
+ _builder_1.newLine();
+ _builder_1.append("\t\t");
+ _builder_1.append("* Comment");
+ _builder_1.newLine();
+ _builder_1.append("\t\t");
+ _builder_1.append("*/");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("@ChangeDoc");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("private Object object");
+ _builder_1.newLine();
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("/** ");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("* Comment");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("*/");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("private Object object2");
+ _builder_1.newLine();
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("/** ");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("* Comment");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("*/");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("@ChangeDoc");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("new() {");
+ _builder_1.newLine();
+ _builder_1.append("\t\t");
+ _builder_1.append("this(new Object, new Object)");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("}");
+ _builder_1.newLine();
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("/** ");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("* Comment");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("*/");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("new(Object object, Object object2) {");
+ _builder_1.newLine();
+ _builder_1.append("\t\t");
+ _builder_1.append("this.object = object");
+ _builder_1.newLine();
+ _builder_1.append("\t\t");
+ _builder_1.append("this.object2 = object2");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("}");
+ _builder_1.newLine();
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("/** ");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("* Comment");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("*/");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("@ChangeDoc");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("def op() {");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("}");
+ _builder_1.newLine();
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("/** ");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("* Comment");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("*/");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("def op2() {");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("}");
+ _builder_1.newLine();
+ _builder_1.newLine();
+ _builder_1.append("}");
+ _builder_1.newLine();
+ Pair<String,String> _mappedTo_1 = Pair.<String, String>of("usercode/UserCode.xtend", _builder_1.toString());
+ final Procedure1<CompilationUnitImpl> _function = new Procedure1<CompilationUnitImpl>() {
+ public void apply(final CompilationUnitImpl it) {
+ XtendFile _xtendFile = it.getXtendFile();
+ EList<XtendTypeDeclaration> _xtendTypes = _xtendFile.getXtendTypes();
+ Iterable<XtendClass> _filter = Iterables.<XtendClass>filter(_xtendTypes, XtendClass.class);
+ final XtendClass xtendClass = IterableExtensions.<XtendClass>head(_filter);
+ StringConcatenation _builder = new StringConcatenation();
+ _builder.append("@<a href=\"eclipse-xtext-doc:platform:/resource/macroProject/src/annotation/ChangeDoc.xtend%23/1\">ChangeDoc</a><br>Hello World!");
+ String _string = _builder.toString();
+ String _documentation = ActiveAnnotationsProcessingInIDETest.this.documentationProvider.getDocumentation(xtendClass);
+ Assert.assertEquals(_string, _documentation);
+ EList<XtendMember> _members = xtendClass.getMembers();
+ Iterable<XtendField> _filter_1 = Iterables.<XtendField>filter(_members, XtendField.class);
+ final Function1<XtendField,Boolean> _function = new Function1<XtendField,Boolean>() {
+ public Boolean apply(final XtendField it) {
+ String _name = it.getName();
+ boolean _equals = _name.equals("object");
+ return Boolean.valueOf(_equals);
+ }
+ };
+ Iterable<XtendField> _filter_2 = IterableExtensions.<XtendField>filter(_filter_1, _function);
+ final XtendField objectField = IterableExtensions.<XtendField>head(_filter_2);
+ StringConcatenation _builder_1 = new StringConcatenation();
+ _builder_1.append("@<a href=\"eclipse-xtext-doc:platform:/resource/macroProject/src/annotation/ChangeDoc.xtend%23/1\">ChangeDoc</a><br>Hello World!");
+ String _string_1 = _builder_1.toString();
+ String _documentation_1 = ActiveAnnotationsProcessingInIDETest.this.documentationProvider.getDocumentation(objectField);
+ Assert.assertEquals(_string_1, _documentation_1);
+ EList<XtendMember> _members_1 = xtendClass.getMembers();
+ Iterable<XtendField> _filter_3 = Iterables.<XtendField>filter(_members_1, XtendField.class);
+ final Function1<XtendField,Boolean> _function_1 = new Function1<XtendField,Boolean>() {
+ public Boolean apply(final XtendField it) {
+ String _name = it.getName();
+ boolean _equals = _name.equals("object2");
+ return Boolean.valueOf(_equals);
+ }
+ };
+ Iterable<XtendField> _filter_4 = IterableExtensions.<XtendField>filter(_filter_3, _function_1);
+ final XtendField objectField2 = IterableExtensions.<XtendField>head(_filter_4);
+ StringConcatenation _builder_2 = new StringConcatenation();
+ _builder_2.append("Comment");
+ String _string_2 = _builder_2.toString();
+ String _documentation_2 = ActiveAnnotationsProcessingInIDETest.this.documentationProvider.getDocumentation(objectField2);
+ Assert.assertEquals(_string_2, _documentation_2);
+ EList<XtendMember> _members_2 = xtendClass.getMembers();
+ Iterable<XtendConstructor> _filter_5 = Iterables.<XtendConstructor>filter(_members_2, XtendConstructor.class);
+ final Function1<XtendConstructor,Boolean> _function_2 = new Function1<XtendConstructor,Boolean>() {
+ public Boolean apply(final XtendConstructor it) {
+ EList<XtendParameter> _parameters = it.getParameters();
+ boolean _isEmpty = _parameters.isEmpty();
+ return Boolean.valueOf(_isEmpty);
+ }
+ };
+ Iterable<XtendConstructor> _filter_6 = IterableExtensions.<XtendConstructor>filter(_filter_5, _function_2);
+ final XtendConstructor constructor = IterableExtensions.<XtendConstructor>head(_filter_6);
+ StringConcatenation _builder_3 = new StringConcatenation();
+ _builder_3.append("@<a href=\"eclipse-xtext-doc:platform:/resource/macroProject/src/annotation/ChangeDoc.xtend%23/1\">ChangeDoc</a><br>Hello World!");
+ String _string_3 = _builder_3.toString();
+ String _documentation_3 = ActiveAnnotationsProcessingInIDETest.this.documentationProvider.getDocumentation(constructor);
+ Assert.assertEquals(_string_3, _documentation_3);
+ EList<XtendMember> _members_3 = xtendClass.getMembers();
+ Iterable<XtendConstructor> _filter_7 = Iterables.<XtendConstructor>filter(_members_3, XtendConstructor.class);
+ final Function1<XtendConstructor,Boolean> _function_3 = new Function1<XtendConstructor,Boolean>() {
+ public Boolean apply(final XtendConstructor it) {
+ EList<XtendParameter> _parameters = it.getParameters();
+ int _size = _parameters.size();
+ boolean _equals = (_size == 2);
+ return Boolean.valueOf(_equals);
+ }
+ };
+ Iterable<XtendConstructor> _filter_8 = IterableExtensions.<XtendConstructor>filter(_filter_7, _function_3);
+ final XtendConstructor constructor2 = IterableExtensions.<XtendConstructor>head(_filter_8);
+ StringConcatenation _builder_4 = new StringConcatenation();
+ _builder_4.append("Comment<dl><dt>Parameters:</dt><dd><b>object</b> </dd><dd><b>object2</b> </dd></dl>");
+ String _string_4 = _builder_4.toString();
+ String _documentation_4 = ActiveAnnotationsProcessingInIDETest.this.documentationProvider.getDocumentation(constructor2);
+ Assert.assertEquals(_string_4, _documentation_4);
+ EList<XtendMember> _members_4 = xtendClass.getMembers();
+ Iterable<XtendFunction> _filter_9 = Iterables.<XtendFunction>filter(_members_4, XtendFunction.class);
+ final Function1<XtendFunction,Boolean> _function_4 = new Function1<XtendFunction,Boolean>() {
+ public Boolean apply(final XtendFunction it) {
+ String _name = it.getName();
+ boolean _equals = _name.equals("op");
+ return Boolean.valueOf(_equals);
+ }
+ };
+ Iterable<XtendFunction> _filter_10 = IterableExtensions.<XtendFunction>filter(_filter_9, _function_4);
+ final XtendFunction opFunction = IterableExtensions.<XtendFunction>head(_filter_10);
+ StringConcatenation _builder_5 = new StringConcatenation();
+ _builder_5.append("@<a href=\"eclipse-xtext-doc:platform:/resource/macroProject/src/annotation/ChangeDoc.xtend%23/1\">ChangeDoc</a><br>Hello World!");
+ String _string_5 = _builder_5.toString();
+ String _documentation_5 = ActiveAnnotationsProcessingInIDETest.this.documentationProvider.getDocumentation(opFunction);
+ Assert.assertEquals(_string_5, _documentation_5);
+ EList<XtendMember> _members_5 = xtendClass.getMembers();
+ Iterable<XtendFunction> _filter_11 = Iterables.<XtendFunction>filter(_members_5, XtendFunction.class);
+ final Function1<XtendFunction,Boolean> _function_5 = new Function1<XtendFunction,Boolean>() {
+ public Boolean apply(final XtendFunction it) {
+ String _name = it.getName();
+ boolean _equals = _name.equals("op2");
+ return Boolean.valueOf(_equals);
+ }
+ };
+ Iterable<XtendFunction> _filter_12 = IterableExtensions.<XtendFunction>filter(_filter_11, _function_5);
+ final XtendFunction op2Function = IterableExtensions.<XtendFunction>head(_filter_12);
+ StringConcatenation _builder_6 = new StringConcatenation();
+ _builder_6.append("Comment");
+ String _string_6 = _builder_6.toString();
+ String _documentation_6 = ActiveAnnotationsProcessingInIDETest.this.documentationProvider.getDocumentation(op2Function);
+ Assert.assertEquals(_string_6, _documentation_6);
+ }
+ };
+ this.assertProcessing(_mappedTo, _mappedTo_1, _function);
+ }
+
+ @Test
+ public void testFileSystemAccess() {
+ StringConcatenation _builder = new StringConcatenation();
+ _builder.append("package myusercode");
+ _builder.newLine();
+ _builder.newLine();
+ _builder.append("@myannotation.MyAnnotation");
+ _builder.newLine();
+ _builder.append("class MyClass {");
+ _builder.newLine();
+ _builder.append("}");
+ _builder.newLine();
+ final String userCodeContent = _builder.toString();
+ StringConcatenation _builder_1 = new StringConcatenation();
+ _builder_1.append("package myannotation");
+ _builder_1.newLine();
+ _builder_1.newLine();
+ _builder_1.append("import org.eclipse.xtend.lib.macro.Active");
+ _builder_1.newLine();
+ _builder_1.append("import org.eclipse.xtend.lib.macro.TransformationContext");
+ _builder_1.newLine();
+ _builder_1.append("import org.eclipse.xtend.lib.macro.AbstractClassProcessor");
+ _builder_1.newLine();
+ _builder_1.append("import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration");
+ _builder_1.newLine();
+ _builder_1.newLine();
+ _builder_1.append("@Active(typeof(MyAnnotationProcessor))");
+ _builder_1.newLine();
+ _builder_1.append("annotation MyAnnotation{ }");
+ _builder_1.newLine();
+ _builder_1.append("class MyAnnotationProcessor extends AbstractClassProcessor {");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("override doTransform(MutableClassDeclaration clazz, extension TransformationContext context) {");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.append("}");
+ _builder_1.newLine();
+ _builder_1.append("\t");
+ _builder_1.newLine();
+ _builder_1.append("}");
+ _builder_1.newLine();
+ Pair<String,String> _mappedTo = Pair.<String, String>of("myannotation/MyAnnotation.xtend", _builder_1.toString());
+ Pair<String,String> _mappedTo_1 = Pair.<String, String>of("myusercode/UserCode.xtend", userCodeContent);
+ final Procedure1<CompilationUnitImpl> _function = new Procedure1<CompilationUnitImpl>() {
+ public void apply(final CompilationUnitImpl it) {
+ FolderHandle _sourceFolder = it.getSourceFolder();
+ Assert.assertNotNull(_sourceFolder);
+ FolderHandle _sourceFolder_1 = it.getSourceFolder();
+ boolean _exists = _sourceFolder_1.exists();
+ Assert.assertTrue(_exists);
+ FolderHandle _sourceFolder_2 = it.getSourceFolder();
+ String _name = _sourceFolder_2.getName();
+ Assert.assertEquals("src", _name);
+ FolderHandle _sourceFolder_3 = it.getSourceFolder();
+ String _path = _sourceFolder_3.getPath();
+ boolean _endsWith = _path.endsWith("/userProject/src");
+ Assert.assertTrue(_endsWith);
+ FolderHandle _targetFolder = it.getTargetFolder();
+ Assert.assertNotNull(_targetFolder);
+ FolderHandle _targetFolder_1 = it.getTargetFolder();
+ boolean _exists_1 = _targetFolder_1.exists();
+ Assert.assertTrue(_exists_1);
+ FolderHandle _targetFolder_2 = it.getTargetFolder();
+ String _name_1 = _targetFolder_2.getName();
+ Assert.assertEquals("xtend-gen", _name_1);
+ FolderHandle _targetFolder_3 = it.getTargetFolder();
+ String _path_1 = _targetFolder_3.getPath();
+ boolean _endsWith_1 = _path_1.endsWith("/userProject/xtend-gen");
+ Assert.assertTrue(_endsWith_1);
+ FolderHandle _rootFolder = it.getRootFolder();
+ Assert.assertNotNull(_rootFolder);
+ FolderHandle _rootFolder_1 = it.getRootFolder();
+ boolean _exists_2 = _rootFolder_1.exists();
+ Assert.assertTrue(_exists_2);
+ FolderHandle _rootFolder_2 = it.getRootFolder();
+ String _name_2 = _rootFolder_2.getName();
+ Assert.assertEquals("userProject", _name_2);
+ FolderHandle _rootFolder_3 = it.getRootFolder();
+ String _path_2 = _rootFolder_3.getPath();
+ boolean _endsWith_2 = _path_2.endsWith("/userProject");
+ Assert.assertTrue(_endsWith_2);
+ FolderHandle _sourceFolder_4 = it.getSourceFolder();
+ final FolderHandle myusercodeFolder = _sourceFolder_4.getFolder("myusercode");
+ Assert.assertNotNull(myusercodeFolder);
+ boolean _exists_3 = myusercodeFolder.exists();
+ Assert.assertTrue(_exists_3);
+ String _name_3 = myusercodeFolder.getName();
+ Assert.assertEquals("myusercode", _name_3);
+ String _path_3 = myusercodeFolder.getPath();
+ boolean _endsWith_3 = _path_3.endsWith("/userProject/src/myusercode");
+ Assert.assertTrue(_endsWith_3);
+ try {
+ FolderHandle _sourceFolder_5 = it.getSourceFolder();
+ _sourceFolder_5.getFolder("myusercode/UserCode.xtend");
+ Assert.fail();
+ } catch (final Throwable _t) {
+ if (_t instanceof IllegalStateException) {
+ final IllegalStateException e = (IllegalStateException)_t;
+ String _message = e.getMessage();
+ boolean _contains = _message.contains("/userProject/src/myusercode/UserCode.xtend");
+ Assert.assertTrue(_contains);
+ } else {
+ throw Exceptions.sneakyThrow(_t);
+ }
+ }
+ FolderHandle _sourceFolder_6 = it.getSourceFolder();
+ final FileHandle userCodeFile = _sourceFolder_6.getFile("myusercode/UserCode.xtend");
+ Assert.assertNotNull(userCodeFile);
+ boolean _exists_4 = userCodeFile.exists();
+ Assert.assertTrue(_exists_4);
+ String _name_4 = userCodeFile.getName();
+ Assert.assertEquals("UserCode.xtend", _name_4);
+ String _path_4 = userCodeFile.getPath();
+ boolean _endsWith_4 = _path_4.endsWith("/userProject/src/myusercode/UserCode.xtend");
+ Assert.assertTrue(_endsWith_4);
+ try {
+ FolderHandle _sourceFolder_7 = it.getSourceFolder();
+ _sourceFolder_7.getFile("myusercode");
+ Assert.fail();
+ } catch (final Throwable _t_1) {
+ if (_t_1 instanceof IllegalStateException) {
+ final IllegalStateException e_1 = (IllegalStateException)_t_1;
+ String _message_1 = e_1.getMessage();
+ boolean _contains_1 = _message_1.contains("/userProject/src/myusercode");
+ Assert.assertTrue(_contains_1);
+ } else {
+ throw Exceptions.sneakyThrow(_t_1);
+ }
+ }
+ String _contents = userCodeFile.getContents();
+ Assert.assertEquals(userCodeContent, _contents);
+ final Procedure1<InputStream> _function = new Procedure1<InputStream>() {
+ public void apply(final InputStream it) {
+ try {
+ InputStreamReader _inputStreamReader = new InputStreamReader(it);
+ String _string = CharStreams.toString(_inputStreamReader);
+ Assert.assertEquals(userCodeContent, _string);
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+ };
+ userCodeFile.read(_function);
+ FolderHandle _sourceFolder_8 = it.getSourceFolder();
+ final FileHandle userCodeCss = _sourceFolder_8.getFile("myusercode/UserCode.css");
+ Assert.assertNotNull(userCodeCss);
+ boolean _exists_5 = userCodeCss.exists();
+ Assert.assertFalse(_exists_5);
+ String _name_5 = userCodeCss.getName();
+ Assert.assertEquals("UserCode.css", _name_5);
+ String _path_5 = userCodeCss.getPath();
+ boolean _endsWith_5 = _path_5.endsWith("/userProject/src/myusercode/UserCode.css");
+ Assert.assertTrue(_endsWith_5);
+ final String helloWorldCssClassDeclaration = ".helloWorldCssClass {}";
+ final Function1<FileHandle,CharSequence> _function_1 = new Function1<FileHandle,CharSequence>() {
+ public CharSequence apply(final FileHandle it) {
+ return ((CharSequence) helloWorldCssClassDeclaration);
+ }
+ };
+ userCodeCss.writeContents(_function_1);
+ FolderHandle _sourceFolder_9 = it.getSourceFolder();
+ final FileHandle userCodeCss2 = _sourceFolder_9.getFile("myusercode/UserCode.css");
+ Assert.assertNotNull(userCodeCss2);
+ boolean _exists_6 = userCodeCss2.exists();
+ Assert.assertTrue(_exists_6);
+ String _contents_1 = userCodeCss2.getContents();
+ Assert.assertEquals(helloWorldCssClassDeclaration, _contents_1);
+ FolderHandle _sourceFolder_10 = it.getSourceFolder();
+ final FileHandle userCode2Css = _sourceFolder_10.getFile("com/itemis/myusercode/UserCode2.css");
+ Assert.assertNotNull(userCode2Css);
+ boolean _exists_7 = userCode2Css.exists();
+ Assert.assertFalse(_exists_7);
+ String _name_6 = userCode2Css.getName();
+ Assert.assertEquals("UserCode2.css", _name_6);
+ String _path_6 = userCode2Css.getPath();
+ boolean _endsWith_6 = _path_6.endsWith("/userProject/src/com/itemis/myusercode/UserCode2.css");
+ Assert.assertTrue(_endsWith_6);
+ final Procedure1<OutputStream> _function_2 = new Procedure1<OutputStream>() {
+ public void apply(final OutputStream it) {
+ final Function0<BufferedWriter> _function = new Function0<BufferedWriter>() {
+ public BufferedWriter apply() {
+ OutputStreamWriter _outputStreamWriter = new OutputStreamWriter(it);
+ BufferedWriter _bufferedWriter = new BufferedWriter(_outputStreamWriter);
+ return _bufferedWriter;
+ }
+ };
+ final Procedure1<BufferedWriter> _function_1 = new Procedure1<BufferedWriter>() {
+ public void apply(final BufferedWriter it) {
+ try {
+ it.write(helloWorldCssClassDeclaration);
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+ };
+ IOUtils.<BufferedWriter>tryWith(_function, _function_1);
+ }
+ };
+ userCode2Css.write(_function_2);
+ FolderHandle _sourceFolder_11 = it.getSourceFolder();
+ final FileHandle userCode2Css2 = _sourceFolder_11.getFile("com/itemis/myusercode/UserCode2.css");
+ Assert.assertNotNull(userCode2Css2);
+ boolean _exists_8 = userCode2Css2.exists();
+ Assert.assertTrue(_exists_8);
+ String _contents_2 = userCode2Css2.getContents();
+ Assert.assertEquals(helloWorldCssClassDeclaration, _contents_2);
+ }
+ };
+ this.assertProcessing(_mappedTo, _mappedTo_1, _function);
+ }
+
@Inject
private XtextResourceSetProvider resourceSetProvider;
@@ -99,11 +648,8 @@ public class ActiveAnnotationsProcessingInIDETest extends AbstractReusableActive
final String packageName = _substring.replace("/", ".");
this.addExportedPackage(this.macroProject, packageName);
}
- IProject _createPluginProject_1 = WorkbenchTestHelper.createPluginProject("userProject", "com.google.inject",
- "org.eclipse.xtend.lib",
- "org.eclipse.xtext.xbase.lib",
- "org.eclipse.xtend.ide.tests.data",
- "org.junit4", "macroProject");
+ IProject _createPluginProject_1 = WorkbenchTestHelper.createPluginProject("userProject", "com.google.inject", "org.eclipse.xtend.lib",
+ "org.eclipse.xtext.xbase.lib", "org.eclipse.xtend.ide.tests.data", "org.junit4", "macroProject");
IJavaProject _create_1 = JavaCore.create(_createPluginProject_1);
this.userProject = _create_1;
String _key_3 = clientFile.getKey();