diff --git a/org.eclipse.xtend.core.tests/src/org/eclipse/xtend/core/tests/jvmmodel/JvmModelTests.xtend b/org.eclipse.xtend.core.tests/src/org/eclipse/xtend/core/tests/jvmmodel/JvmModelTests.xtend index d5027d17cd5..4ec6222687e 100644 --- a/org.eclipse.xtend.core.tests/src/org/eclipse/xtend/core/tests/jvmmodel/JvmModelTests.xtend +++ b/org.eclipse.xtend.core.tests/src/org/eclipse/xtend/core/tests/jvmmodel/JvmModelTests.xtend @@ -219,7 +219,7 @@ class JvmModelTests extends AbstractXtendTestCase { assertTrue(anonymous.final) assertFalse(anonymous.static) assertTrue(anonymous.local) - assertFalse(anonymous.anonymous) // additional member -> named local class + assertTrue(anonymous.anonymous) assertEquals(JvmVisibility.DEFAULT, anonymous.visibility) assertEquals(2, anonymous.superTypes.size) assertEquals('java.lang.Runnable', anonymous.superTypes.last.qualifiedName) diff --git a/org.eclipse.xtend.core.tests/xtend-gen/org/eclipse/xtend/core/tests/jvmmodel/JvmModelTests.java b/org.eclipse.xtend.core.tests/xtend-gen/org/eclipse/xtend/core/tests/jvmmodel/JvmModelTests.java index dc0439274e6..507ecd3cb50 100644 --- a/org.eclipse.xtend.core.tests/xtend-gen/org/eclipse/xtend/core/tests/jvmmodel/JvmModelTests.java +++ b/org.eclipse.xtend.core.tests/xtend-gen/org/eclipse/xtend/core/tests/jvmmodel/JvmModelTests.java @@ -371,7 +371,7 @@ public void testAnonymousClass_01() { Assert.assertTrue(anonymous.isFinal()); Assert.assertFalse(anonymous.isStatic()); Assert.assertTrue(anonymous.isLocal()); - Assert.assertFalse(anonymous.isAnonymous()); + Assert.assertTrue(anonymous.isAnonymous()); Assert.assertEquals(JvmVisibility.DEFAULT, anonymous.getVisibility()); Assert.assertEquals(2, anonymous.getSuperTypes().size()); Assert.assertEquals("java.lang.Runnable", IterableExtensions.last(anonymous.getSuperTypes()).getQualifiedName()); diff --git a/org.eclipse.xtend.core/META-INF/MANIFEST.MF b/org.eclipse.xtend.core/META-INF/MANIFEST.MF index f45c7e7f009..c6c8675695c 100644 --- a/org.eclipse.xtend.core/META-INF/MANIFEST.MF +++ b/org.eclipse.xtend.core/META-INF/MANIFEST.MF @@ -10,6 +10,7 @@ Bundle-RequiredExecutionEnvironment: JavaSE-11 Export-Package: org.eclipse.xtend.core;version="2.34.0";x-friends:="org.eclipse.xtend.ide.common,org.eclipse.xtend.ide.tests,org.eclipse.xtend.core.tests", org.eclipse.xtend.core.compiler;version="2.34.0";x-friends:="org.eclipse.xtend.m2e,org.eclipse.xtend.ide.tests,org.eclipse.xtend.core.tests", org.eclipse.xtend.core.compiler.batch;version="2.34.0", + org.eclipse.xtend.core.compiler.output;version="2.34.0";x-internal:=true, org.eclipse.xtend.core.conversion;version="2.34.0";x-friends:="org.eclipse.xtend.ide,org.eclipse.xtend.ide.common,org.eclipse.xtend.core.tests", org.eclipse.xtend.core.documentation;version="2.34.0";x-internal:=true, org.eclipse.xtend.core.findReferences;version="2.34.0";x-internal:=true, diff --git a/org.eclipse.xtend.core/src/org/eclipse/xtend/core/compiler/AnonymousClassCompilerHelper.java b/org.eclipse.xtend.core/src/org/eclipse/xtend/core/compiler/AnonymousClassCompilerHelper.java new file mode 100644 index 00000000000..977e46ebd7e --- /dev/null +++ b/org.eclipse.xtend.core/src/org/eclipse/xtend/core/compiler/AnonymousClassCompilerHelper.java @@ -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 AnonymousClassCompilerHelper { + + @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; + }); + } +} diff --git a/org.eclipse.xtend.core/src/org/eclipse/xtend/core/compiler/XtendCompiler.java b/org.eclipse.xtend.core/src/org/eclipse/xtend/core/compiler/XtendCompiler.java index a96f6e071bc..ce98e5c917c 100644 --- a/org.eclipse.xtend.core/src/org/eclipse/xtend/core/compiler/XtendCompiler.java +++ b/org.eclipse.xtend.core/src/org/eclipse/xtend/core/compiler/XtendCompiler.java @@ -14,7 +14,6 @@ import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.xtend.core.jvmmodel.IXtendJvmAssociations; import org.eclipse.xtend.core.richstring.AbstractRichStringPartAcceptor; import org.eclipse.xtend.core.richstring.DefaultIndentationHandler; import org.eclipse.xtend.core.richstring.RichStringProcessor; @@ -34,7 +33,6 @@ import org.eclipse.xtext.common.types.JvmFeature; import org.eclipse.xtext.common.types.JvmField; import org.eclipse.xtext.common.types.JvmFormalParameter; -import org.eclipse.xtext.common.types.JvmGenericType; import org.eclipse.xtext.common.types.JvmIdentifiableElement; import org.eclipse.xtext.common.types.JvmType; import org.eclipse.xtext.common.types.JvmTypeReference; @@ -85,7 +83,7 @@ public class XtendCompiler extends XbaseCompiler { private IGeneratorConfigProvider generatorConfigProvider; @Inject - private IXtendJvmAssociations associations; + private AnonymousClassCompilerHelper compilerHelper; @Override protected String getFavoriteVariableName(EObject ex) { @@ -546,9 +544,7 @@ protected void _toJavaStatement(final AnonymousClass anonymousClass, ITreeAppend @Override protected boolean internalCanCompileToJavaExpression(XExpression expression, ITreeAppendable appendable) { if(expression instanceof AnonymousClass) { - AnonymousClass anonymousClass = (AnonymousClass) expression; - JvmGenericType inferredLocalClass = associations.getInferredType(anonymousClass); - return inferredLocalClass.isAnonymous(); + return compilerHelper.canCompileToJavaAnonymousClass((AnonymousClass) expression); } else return super.internalCanCompileToJavaExpression(expression, appendable); } @@ -611,5 +607,10 @@ protected boolean needSyntheticSelfVariable(XClosure closure, LightweightTypeRef } return false; } - + + @Override + protected boolean canCompileToJavaAnonymousClass(XConstructorCall constructorCall) { + return super.canCompileToJavaAnonymousClass(constructorCall) && + compilerHelper.canCompileToJavaAnonymousClass((AnonymousClass) constructorCall.eContainer()); + } } diff --git a/org.eclipse.xtend.core/src/org/eclipse/xtend/core/compiler/XtendGenerator.xtend b/org.eclipse.xtend.core/src/org/eclipse/xtend/core/compiler/XtendGenerator.xtend index 1f9700a18e5..175279db09a 100644 --- a/org.eclipse.xtend.core/src/org/eclipse/xtend/core/compiler/XtendGenerator.xtend +++ b/org.eclipse.xtend.core/src/org/eclipse/xtend/core/compiler/XtendGenerator.xtend @@ -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 AnonymousClassCompilerHelper 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)) { + 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,7 @@ class XtendGenerator extends JvmModelGenerator implements IGenerator2 { } if (declaringType.local && it instanceof JvmOperation) { val declarator = declaringType as JvmGenericType - if (!declarator.anonymous) { + if (!compilerHelper.canCompileToJavaAnonymousClass(declarator)) { return result } } @@ -386,5 +396,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) + } + } \ No newline at end of file diff --git a/org.eclipse.xtend.core/src/org/eclipse/xtend/core/compiler/output/AnonymousClassAwareTreeAppendable.java b/org.eclipse.xtend.core/src/org/eclipse/xtend/core/compiler/output/AnonymousClassAwareTreeAppendable.java new file mode 100644 index 00000000000..d76c5bcba32 --- /dev/null +++ b/org.eclipse.xtend.core/src/org/eclipse/xtend/core/compiler/output/AnonymousClassAwareTreeAppendable.java @@ -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.AnonymousClassCompilerHelper; +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 AnonymousClassCompilerHelper compilerHelper; + + public AnonymousClassAwareTreeAppendable(AnonymousClassCompilerHelper 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(AnonymousClassCompilerHelper compilerHelper, SharedAppendableState state, ITraceURIConverter converter, + ILocationInFileProvider locationProvider, IJvmModelAssociations jvmModelAssociations, Set 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 newData, boolean useForDebugging) { + return new AnonymousClassAwareTreeAppendable(compilerHelper, state, converter, locationProvider, jvmModelAssociations, newData, useForDebugging); + } + +} diff --git a/org.eclipse.xtend.core/src/org/eclipse/xtend/core/jvmmodel/XtendJvmModelInferrer.java b/org.eclipse.xtend.core/src/org/eclipse/xtend/core/jvmmodel/XtendJvmModelInferrer.java index bb0cd37c759..92ebb0be521 100644 --- a/org.eclipse.xtend.core/src/org/eclipse/xtend/core/jvmmodel/XtendJvmModelInferrer.java +++ b/org.eclipse.xtend.core/src/org/eclipse/xtend/core/jvmmodel/XtendJvmModelInferrer.java @@ -852,7 +852,7 @@ public void inferLocalClass( JvmFeature container) { final JvmGenericType inferredType = typesFactory.createJvmGenericType(); inferredType.setSimpleName(localClassName); - inferredType.setAnonymous(!hasAdditionalMembers(anonymousClass)); + inferredType.setAnonymous(true); inferredType.setFinal(true); inferredType.setVisibility(JvmVisibility.DEFAULT); inferredType.getSuperTypes().add(jvmTypesBuilder.inferredType(anonymousClass)); @@ -873,14 +873,5 @@ public void inferLocalClass( associator.associateLogicalContainer(actualParameter, container); } } - - protected boolean hasAdditionalMembers(AnonymousClass anonymousClass) { - for(XtendMember member: anonymousClass.getMembers()) { - if(member instanceof XtendField || - (member instanceof XtendFunction && !((XtendFunction) member).isOverride())) - return true; - } - return false; - } - + } diff --git a/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/compiler/XtendGenerator.java b/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/compiler/XtendGenerator.java index d84d513d5d3..82852612615 100644 --- a/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/compiler/XtendGenerator.java +++ b/org.eclipse.xtend.core/xtend-gen/org/eclipse/xtend/core/compiler/XtendGenerator.java @@ -20,6 +20,7 @@ import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.xtend.core.compiler.output.AnonymousClassAwareTreeAppendable; import org.eclipse.xtend.core.macro.ActiveAnnotationContext; import org.eclipse.xtend.core.macro.ActiveAnnotationContexts; import org.eclipse.xtend.core.macro.CodeGenerationContextImpl; @@ -48,6 +49,8 @@ import org.eclipse.xtext.generator.IFileSystemAccess2; import org.eclipse.xtext.generator.IGenerator2; import org.eclipse.xtext.generator.IGeneratorContext; +import org.eclipse.xtext.generator.trace.ITraceURIConverter; +import org.eclipse.xtext.resource.ILocationInFileProvider; import org.eclipse.xtext.service.OperationCanceledManager; import org.eclipse.xtext.util.Strings; import org.eclipse.xtext.xbase.XAbstractFeatureCall; @@ -55,11 +58,14 @@ import org.eclipse.xtext.xbase.XExpression; import org.eclipse.xtext.xbase.compiler.ElementIssueProvider; import org.eclipse.xtext.xbase.compiler.GeneratorConfig; +import org.eclipse.xtext.xbase.compiler.ImportManager; import org.eclipse.xtext.xbase.compiler.JvmModelGenerator; import org.eclipse.xtext.xbase.compiler.LoopParams; import org.eclipse.xtext.xbase.compiler.output.ITreeAppendable; import org.eclipse.xtext.xbase.compiler.output.ImportingStringConcatenation; 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.lib.CollectionLiterals; import org.eclipse.xtext.xbase.lib.Exceptions; import org.eclipse.xtext.xbase.lib.Functions.Function1; @@ -91,6 +97,9 @@ private static class StopCollecting extends Exception { @Inject private ElementIssueProvider.Factory issueProviderFactory; + @Inject + private AnonymousClassCompilerHelper compilerHelper; + @Override public void doGenerate(final Resource input, final IFileSystemAccess fsa) { super.doGenerate(input, fsa); @@ -251,14 +260,14 @@ public String reassignThisType(final ITreeAppendable b, final JvmDeclaredType de } public void compileLocalTypeStubs(final JvmFeature feature, final ITreeAppendable appendable, final GeneratorConfig config) { - final Function1 _function = (JvmGenericType it) -> { - boolean _isAnonymous = it.isAnonymous(); - return Boolean.valueOf((!_isAnonymous)); - }; - final Consumer _function_1 = (JvmGenericType it) -> { - appendable.newLine(); + final Consumer _function = (JvmGenericType it) -> { + boolean _canCompileToJavaAnonymousClass = this.compilerHelper.canCompileToJavaAnonymousClass(it); + if (_canCompileToJavaAnonymousClass) { + return; + } EObject _head = IterableExtensions.head(this.getSourceElements(it)); final AnonymousClass anonymousClass = ((AnonymousClass) _head); + appendable.newLine(); final ITreeAppendable childAppendable = appendable.trace(anonymousClass); childAppendable.append("abstract class "); this._treeAppendableUtil.traceSignificant(childAppendable, anonymousClass).append(it.getSimpleName()); @@ -277,10 +286,10 @@ public void compileLocalTypeStubs(final JvmFeature feature, final ITreeAppendabl childAppendable.newLine().append("final ").append(it.getSimpleName()).append(" ").append(thisName).append(" = this;"); childAppendable.blankLine(); } - final Procedure1 _function_2 = (LoopParams it_1) -> { + final Procedure1 _function_1 = (LoopParams it_1) -> { it_1.setSeparator(this.memberSeparator()); }; - final Procedure1 _function_3 = (JvmMember it_1) -> { + final Procedure1 _function_2 = (JvmMember it_1) -> { final ITreeAppendable memberAppendable = this._treeAppendableUtil.traceWithComments(childAppendable, it_1); memberAppendable.openScope(); if ((it_1 instanceof JvmOperation)) { @@ -345,11 +354,11 @@ public void compileLocalTypeStubs(final JvmFeature feature, final ITreeAppendabl } memberAppendable.closeScope(); }; - this._loopExtensions.forEach(childAppendable, this.getAddedDeclarations(it, anonymousClass), _function_2, _function_3); + this._loopExtensions.forEach(childAppendable, this.getAddedDeclarations(it, anonymousClass), _function_1, _function_2); childAppendable.decreaseIndentation().newLine().append("}"); appendable.blankLine(); }; - IterableExtensions.filter(feature.getLocalClasses(), _function).forEach(_function_1); + feature.getLocalClasses().forEach(_function); } private ITreeAppendable generateJavaConstant(final Object value, final ITreeAppendable appendable) { @@ -472,8 +481,8 @@ public ITreeAppendable generateVisibilityModifier(final JvmMember it, final ITre if ((it.getDeclaringType().isLocal() && (it instanceof JvmOperation))) { JvmDeclaredType _declaringType_1 = it.getDeclaringType(); final JvmGenericType declarator = ((JvmGenericType) _declaringType_1); - boolean _isAnonymous = declarator.isAnonymous(); - boolean _not = (!_isAnonymous); + boolean _canCompileToJavaAnonymousClass = this.compilerHelper.canCompileToJavaAnonymousClass(declarator); + boolean _not = (!_canCompileToJavaAnonymousClass); if (_not) { return result; } @@ -574,4 +583,9 @@ public ITreeAppendable generateMembersInBody(final JvmDeclaredType it, final ITr } return _xifexpression; } + + @Override + public TreeAppendable createAppendable(final ImportManager importManager, final ITraceURIConverter converter, final ILocationInFileProvider locationProvider, final IJvmModelAssociations jvmModelAssociations, final EObject source, final String indentation, final String lineSeparator) { + return new AnonymousClassAwareTreeAppendable(this.compilerHelper, importManager, converter, locationProvider, jvmModelAssociations, source, indentation, lineSeparator); + } } diff --git a/org.eclipse.xtext.common.types/src/org/eclipse/xtext/common/types/impl/JvmGenericTypeImplCustom.java b/org.eclipse.xtext.common.types/src/org/eclipse/xtext/common/types/impl/JvmGenericTypeImplCustom.java index 47676fffb75..00f55fcb60f 100644 --- a/org.eclipse.xtext.common.types/src/org/eclipse/xtext/common/types/impl/JvmGenericTypeImplCustom.java +++ b/org.eclipse.xtext.common.types/src/org/eclipse/xtext/common/types/impl/JvmGenericTypeImplCustom.java @@ -40,4 +40,5 @@ public boolean isAnonymous() { checkPendingInitialization(); return super.isAnonymous(); } + } diff --git a/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/compiler/JvmModelGenerator.xtend b/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/compiler/JvmModelGenerator.xtend index d0ee1c5346f..6a827df2650 100644 --- a/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/compiler/JvmModelGenerator.xtend +++ b/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/compiler/JvmModelGenerator.xtend @@ -1002,11 +1002,20 @@ class JvmModelGenerator implements IGenerator { } } - val appendable = new TreeAppendable(importManager, cachingConverter, locationProvider, jvmModelAssociations, context, " ", "\n") + val appendable = createAppendable(importManager, cachingConverter, locationProvider, jvmModelAssociations, context, " ", "\n") appendable.state.generatorConfig = config return appendable } + /** + * @since 2.34 + */ + def protected TreeAppendable createAppendable(ImportManager importManager, ITraceURIConverter converter, + ILocationInFileProvider locationProvider, IJvmModelAssociations jvmModelAssociations, + EObject source, String indentation, String lineSeparator) { + return new TreeAppendable(importManager, converter, locationProvider, jvmModelAssociations, source, indentation, lineSeparator) + } + def JvmGenericType containerType(EObject context) { if(context === null) null diff --git a/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/compiler/XbaseCompiler.java b/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/compiler/XbaseCompiler.java index 6e15a44ed2e..d367dcf93a2 100644 --- a/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/compiler/XbaseCompiler.java +++ b/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/compiler/XbaseCompiler.java @@ -316,7 +316,7 @@ protected ITreeAppendable appendTypeArguments(XAbstractFeatureCall call, ITreeAp } return completeFeatureCallAppendable; } - + @Override protected void internalToConvertedExpression(XExpression obj, ITreeAppendable appendable) { if (obj instanceof XBlockExpression) { diff --git a/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/compiler/output/TreeAppendable.java b/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/compiler/output/TreeAppendable.java index 6b772972a39..876ce43a813 100644 --- a/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/compiler/output/TreeAppendable.java +++ b/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/compiler/output/TreeAppendable.java @@ -195,7 +195,14 @@ protected TreeAppendable trace(Set newData, boolean useForDebuggi * @since 2.4 */ protected TreeAppendable createChild(SharedAppendableState state, ILocationInFileProvider locationProvider, IJvmModelAssociations jvmModelAssociations, Set newData, boolean useForDebugging) { - return new TreeAppendable(state, traceURIConverter, locationProvider, jvmModelAssociations, newData, useForDebugging); + return createChild(state, traceURIConverter, locationProvider, jvmModelAssociations, newData, useForDebugging); + } + + /** + * @since 2.34 + */ + protected TreeAppendable createChild(SharedAppendableState state, ITraceURIConverter converter, ILocationInFileProvider locationProvider, IJvmModelAssociations jvmModelAssociations, Set newData, boolean useForDebugging) { + return new TreeAppendable(state, converter, locationProvider, jvmModelAssociations, newData, useForDebugging); } @Override @@ -646,5 +653,4 @@ protected void dump(String indent) { public GeneratorConfig getGeneratorConfig() { return state.getGeneratorConfig(); } - } diff --git a/org.eclipse.xtext.xbase/xtend-gen/org/eclipse/xtext/xbase/compiler/JvmModelGenerator.java b/org.eclipse.xtext.xbase/xtend-gen/org/eclipse/xtext/xbase/compiler/JvmModelGenerator.java index 06adf343abe..0518874c29f 100644 --- a/org.eclipse.xtext.xbase/xtend-gen/org/eclipse/xtext/xbase/compiler/JvmModelGenerator.java +++ b/org.eclipse.xtext.xbase/xtend-gen/org/eclipse/xtext/xbase/compiler/JvmModelGenerator.java @@ -1499,12 +1499,19 @@ public SourceRelativeURI getURIForTrace(final Resource resource) { return this.uriForTraceCache.get(resource.getURI()); } }; - final TreeAppendable appendable = new TreeAppendable(importManager, cachingConverter, this.locationProvider, this.jvmModelAssociations, context, " ", "\n"); + final TreeAppendable appendable = this.createAppendable(importManager, cachingConverter, this.locationProvider, this.jvmModelAssociations, context, " ", "\n"); SharedAppendableState _state = appendable.getState(); _state.setGeneratorConfig(config); return appendable; } + /** + * @since 2.34 + */ + protected TreeAppendable createAppendable(final ImportManager importManager, final ITraceURIConverter converter, final ILocationInFileProvider locationProvider, final IJvmModelAssociations jvmModelAssociations, final EObject source, final String indentation, final String lineSeparator) { + return new TreeAppendable(importManager, converter, locationProvider, jvmModelAssociations, source, indentation, lineSeparator); + } + public JvmGenericType containerType(final EObject context) { JvmGenericType _xifexpression = null; if ((context == null)) {