-
Notifications
You must be signed in to change notification settings - Fork 320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Xtend refactoring handling of anonymous class #2898
Changes from 43 commits
94cbea8
2494947
2d1328e
839182e
b6d2aca
b20135a
461db35
eb38b9d
5390514
061170c
ae07565
af65508
665d49c
ab8c3fb
5d39e36
c2789f6
e424b1a
944efb0
b2401fe
85a0ea9
63d58e8
d1d795b
e5b112f
ad1b04c
1d822ef
92242b1
c4491d4
c8b774d
ff120dc
34096f7
d6a1a8b
f87ce5e
8f85eb7
f5251c1
e74011b
26d6c23
07a2f7e
723d944
74faea2
15b244d
4f44872
eb6665b
bc766b0
f8d46fd
5d926c2
6af742c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2023 itemis AG (http://www.itemis.eu) and others. | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*******************************************************************************/ | ||
package org.eclipse.xtend.core.compiler; | ||
|
||
import org.eclipse.emf.ecore.EObject; | ||
import org.eclipse.xtend.core.xtend.AnonymousClass; | ||
import org.eclipse.xtend.core.xtend.XtendField; | ||
import org.eclipse.xtend.core.xtend.XtendFunction; | ||
import org.eclipse.xtend.core.xtend.XtendMember; | ||
import org.eclipse.xtext.common.types.JvmType; | ||
import org.eclipse.xtext.util.IResourceScopeCache; | ||
import org.eclipse.xtext.util.Tuples; | ||
import org.eclipse.xtext.xbase.jvmmodel.IJvmModelAssociations; | ||
|
||
import com.google.inject.Inject; | ||
|
||
/** | ||
* @author Lorenzo Bettini - Initial contribution and API | ||
*/ | ||
public class XtendCompilerHelper { | ||
|
||
@Inject | ||
private IResourceScopeCache cache; | ||
|
||
@Inject | ||
private IJvmModelAssociations associations; | ||
|
||
/** | ||
* Assumes that the passed type is anonymous. | ||
*/ | ||
public boolean canCompileToJavaAnonymousClass(JvmType type) { | ||
return cache.get(Tuples.pair("anonymousJava", type), type.eResource(), () -> { | ||
EObject sourceElement = associations.getPrimarySourceElement(type); | ||
return sourceElement instanceof AnonymousClass && | ||
canCompileToJavaAnonymousClass((AnonymousClass) sourceElement); | ||
}); | ||
} | ||
|
||
public boolean canCompileToJavaAnonymousClass(AnonymousClass anonymousClass) { | ||
return cache.get(Tuples.pair("anonymousJava", anonymousClass), anonymousClass.eResource(), () -> { | ||
for(XtendMember member: anonymousClass.getMembers()) { | ||
if(member instanceof XtendField || | ||
(member instanceof XtendFunction && !((XtendFunction) member).isOverride())) | ||
return false; | ||
} | ||
return true; | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,6 +46,12 @@ import org.eclipse.xtext.xbase.compiler.output.ITreeAppendable | |
import org.eclipse.xtext.xbase.compiler.output.SharedAppendableState | ||
import org.eclipse.xtext.xbase.typesystem.IBatchTypeResolver | ||
import org.eclipse.xtext.xbase.typesystem.references.ITypeReferenceOwner | ||
import org.eclipse.xtext.xbase.compiler.ImportManager | ||
import org.eclipse.xtext.generator.trace.ITraceURIConverter | ||
import org.eclipse.xtext.resource.ILocationInFileProvider | ||
import org.eclipse.xtext.xbase.jvmmodel.IJvmModelAssociations | ||
import org.eclipse.emf.ecore.EObject | ||
import org.eclipse.xtend.core.compiler.output.AnonymousClassAwareTreeAppendable | ||
|
||
/** | ||
* @author Sven Efftinge - Initial contribution and API | ||
|
@@ -56,7 +62,8 @@ class XtendGenerator extends JvmModelGenerator implements IGenerator2 { | |
@Inject OperationCanceledManager operationCanceledManager | ||
|
||
@Inject ElementIssueProvider.Factory issueProviderFactory | ||
|
||
@Inject XtendCompilerHelper compilerHelper | ||
|
||
override doGenerate(Resource input, IFileSystemAccess fsa) { | ||
super.doGenerate(input, fsa) | ||
callMacroProcessors(input) | ||
|
@@ -164,9 +171,12 @@ class XtendGenerator extends JvmModelGenerator implements IGenerator2 { | |
} | ||
|
||
def compileLocalTypeStubs(JvmFeature feature, ITreeAppendable appendable, GeneratorConfig config) { | ||
feature.localClasses.filter[ !anonymous ].forEach[ | ||
appendable.newLine | ||
feature.localClasses.forEach[ | ||
if (compilerHelper.canCompileToJavaAnonymousClass(it)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yet this code here doesn't do both. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At least in the current implementation anonymous classes are local classes |
||
return | ||
} | ||
val anonymousClass = sourceElements.head as AnonymousClass | ||
appendable.newLine | ||
val childAppendable = appendable.trace(anonymousClass) | ||
childAppendable.append('abstract class ') | ||
childAppendable.traceSignificant(anonymousClass).append(simpleName) | ||
|
@@ -320,7 +330,9 @@ class XtendGenerator extends JvmModelGenerator implements IGenerator2 { | |
} | ||
if (declaringType.local && it instanceof JvmOperation) { | ||
val declarator = declaringType as JvmGenericType | ||
if (!declarator.anonymous) { | ||
if (!declarator.anonymous || | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure whether I like the fact that the helper doesn't check the declarator itself but this code here has to do both. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indeed I had put a Javadoc comment on the helper https://github.com/eclipse/xtext/pull/2898/files/bc766b0068465148679855a36c8c9c88e5c62065#diff-c6ea2a981e27e70dc2cd53ff982ee051ac65096607807462e10196d625518f88R35 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @szarnekow I've just pushed 6af742c that check for anonymous is redundant |
||
!compilerHelper.canCompileToJavaAnonymousClass(declarator) | ||
) { | ||
return result | ||
} | ||
} | ||
|
@@ -386,5 +398,9 @@ class XtendGenerator extends JvmModelGenerator implements IGenerator2 { | |
} | ||
|
||
} | ||
|
||
|
||
override createAppendable(ImportManager importManager, ITraceURIConverter converter, ILocationInFileProvider locationProvider, IJvmModelAssociations jvmModelAssociations, EObject source, String indentation, String lineSeparator) { | ||
return new AnonymousClassAwareTreeAppendable(compilerHelper, importManager, converter, locationProvider, jvmModelAssociations, source, indentation, lineSeparator) | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2023 itemis AG (http://www.itemis.eu) and others. | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*******************************************************************************/ | ||
package org.eclipse.xtend.core.compiler.output; | ||
|
||
import java.util.Set; | ||
|
||
import org.eclipse.emf.ecore.EObject; | ||
import org.eclipse.xtend.core.compiler.XtendCompilerHelper; | ||
import org.eclipse.xtext.generator.trace.ILocationData; | ||
import org.eclipse.xtext.generator.trace.ITraceURIConverter; | ||
import org.eclipse.xtext.resource.ILocationInFileProvider; | ||
import org.eclipse.xtext.xbase.compiler.ImportManager; | ||
import org.eclipse.xtext.xbase.compiler.output.SharedAppendableState; | ||
import org.eclipse.xtext.xbase.compiler.output.TreeAppendable; | ||
import org.eclipse.xtext.xbase.jvmmodel.IJvmModelAssociations; | ||
import org.eclipse.xtext.xbase.typesystem.references.LightweightTypeReferenceSerializer; | ||
import org.eclipse.xtext.xbase.typesystem.references.ParameterizedTypeReference; | ||
|
||
/** | ||
* A custom implementation that takes into consideration anonymous classes, | ||
* which, in some cases, cannot be compiled into standard Java anonymous classes: | ||
* they are compiled into nested local classes. | ||
* | ||
* It uses a custom {@link LightweightTypeReferenceSerializer}. | ||
* | ||
* @author Lorenzo Bettini - Initial contribution and API | ||
*/ | ||
public class AnonymousClassAwareTreeAppendable extends TreeAppendable { | ||
|
||
private XtendCompilerHelper compilerHelper; | ||
|
||
public AnonymousClassAwareTreeAppendable(XtendCompilerHelper compilerHelper, ImportManager importManager, ITraceURIConverter converter, | ||
ILocationInFileProvider locationProvider, IJvmModelAssociations jvmModelAssociations, EObject source, String indentation, | ||
String lineSeparator) { | ||
super(importManager, converter, locationProvider, jvmModelAssociations, source, indentation, lineSeparator); | ||
this.compilerHelper = compilerHelper; | ||
} | ||
|
||
protected AnonymousClassAwareTreeAppendable(XtendCompilerHelper compilerHelper, SharedAppendableState state, ITraceURIConverter converter, | ||
ILocationInFileProvider locationProvider, IJvmModelAssociations jvmModelAssociations, Set<ILocationData> sourceLocations, | ||
boolean useForDebugging) { | ||
super(state, converter, locationProvider, jvmModelAssociations, sourceLocations, useForDebugging); | ||
this.compilerHelper = compilerHelper; | ||
} | ||
|
||
@Override | ||
protected LightweightTypeReferenceSerializer createLightweightTypeReferenceSerializer() { | ||
return new LightweightTypeReferenceSerializer(this) { | ||
@Override | ||
protected void doVisitParameterizedTypeReference(ParameterizedTypeReference reference) { | ||
if (reference.isAnonymous() && | ||
!compilerHelper.canCompileToJavaAnonymousClass(reference.getType())) { | ||
// serialize the type of the generated nested local class | ||
AnonymousClassAwareTreeAppendable.this.append(reference.getType()); | ||
} else { | ||
super.doVisitParameterizedTypeReference(reference); | ||
} | ||
} | ||
}; | ||
} | ||
|
||
@Override | ||
protected TreeAppendable createChild(SharedAppendableState state, ITraceURIConverter converter, ILocationInFileProvider locationProvider, | ||
IJvmModelAssociations jvmModelAssociations, Set<ILocationData> newData, boolean useForDebugging) { | ||
return new AnonymousClassAwareTreeAppendable(compilerHelper, state, converter, locationProvider, jvmModelAssociations, newData, useForDebugging); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this can only answer whether a JvmType can be compiled to an anonymous class, maybe a more restrictive name should be chosen?
AnonymousClassCompilerHelper
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed that was my second choice, so I'll rename it :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the way, we already have https://github.com/eclipse/xtext/blob/88acf1555988cd81e1756abc0d6d2c3f1f1efa11/org.eclipse.xtend.core/src/org/eclipse/xtend/core/jvmmodel/AnonymousClassUtil.java#L39
should I put the methods of
XtendCompilerHelper
directly there?