remove brittle nested class detection magic from TypeReference

This commit is contained in:
Stefan Oehme 2015-10-21 13:52:33 +02:00
parent 9f4a7ff41a
commit 37218795e8
9 changed files with 60 additions and 56 deletions

View file

@ -20,6 +20,7 @@ import org.eclipse.xtext.xtext.generator.model.GuiceModuleAccess
import static extension org.eclipse.xtext.xtext.generator.model.TypeReference.*
import org.eclipse.xtext.xtext.generator.AbstractXtextGeneratorFragment
import org.eclipse.xtext.xtext.generator.model.TypeReference
class BuilderIntegrationFragment2 extends AbstractXtextGeneratorFragment {
@ -51,7 +52,7 @@ class BuilderIntegrationFragment2 extends AbstractXtextGeneratorFragment {
protected def addEclipsePluginGuiceBindings() {
val StringConcatenationClient statement1 =
'''binder.bind(«IResourceDescriptions».class).annotatedWith(«Names».named(«ResourceDescriptionsProvider».NAMED_BUILDER_SCOPE)).to(«'org.eclipse.xtext.builder.clustering.CurrentDescriptions.ResourceSetAware'.typeRef».class);'''
'''binder.bind(«IResourceDescriptions».class).annotatedWith(«Names».named(«ResourceDescriptionsProvider».NAMED_BUILDER_SCOPE)).to(«new TypeReference('org.eclipse.xtext.builder.clustering', 'CurrentDescriptions.ResourceSetAware')».class);'''
val StringConcatenationClient statement2 =
'''binder.bind(«IResourceDescriptions».class).annotatedWith(«Names».named(«ResourceDescriptionsProvider».PERSISTED_DESCRIPTIONS)).to(«'org.eclipse.xtext.builder.builderState.IBuilderState'.typeRef».class);'''
new GuiceModuleAccess.BindingFactory()

View file

@ -118,7 +118,11 @@ class GeneratorFragment2 extends AbstractStubGeneratingFragment {
protected def contributeEclipsePluginGuiceBindings() {
val StringConcatenationClient expression = '''«'org.eclipse.core.resources.ResourcesPlugin'.typeRef».getWorkspace().getRoot()'''
val StringConcatenationClient statement =
'''binder.bind(«'org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreInitializer'.typeRef».class).annotatedWith(«Names».named("builderPreferenceInitializer")).to(«'org.eclipse.xtext.builder.preferences.BuilderPreferenceAccess.Initializer'.typeRef».class);'''
'''
binder.bind(«'org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreInitializer'.typeRef».class)
.annotatedWith(«Names».named("builderPreferenceInitializer"))
.to(«new TypeReference('org.eclipse.xtext.builder.preferences', 'BuilderPreferenceAccess.Initializer')».class);
'''
new GuiceModuleAccess.BindingFactory()
.addTypeToType('org.eclipse.xtext.builder.IXtextBuilderParticipant'.typeRef,
'org.eclipse.xtext.builder.BuilderParticipant'.typeRef)

View file

@ -99,7 +99,7 @@ class IdeaPluginGenerator extends AbstractXtextGeneratorFragment {
'''binder.bind(«'org.eclipse.xtext.ide.editor.contentassist.antlr.internal.Lexer'.typeRef».class).annotatedWith(«Names».named(«'org.eclipse.xtext.ide.LexerIdeBindings'.typeRef».CONTENT_ASSIST)).to(«caNaming.getLexerClass(grammar)».class);''')
if (grammar.inheritsXbase) {
bindFactory.addTypeToType('org.eclipse.xtext.common.types.xtext.AbstractTypeScopeProvider'.typeRef, 'org.eclipse.xtext.idea.common.types.StubBasedTypeScopeProvider'.typeRef)
bindFactory.addTypeToType('org.eclipse.xtext.xbase.typesystem.internal.IFeatureScopeTracker.Provider'.typeRef, 'org.eclipse.xtext.xbase.typesystem.internal.OptimizingFeatureScopeTrackerProvider'.typeRef)
bindFactory.addTypeToType(new TypeReference('org.eclipse.xtext.xbase.typesystem.internal', 'IFeatureScopeTracker.Provider'), 'org.eclipse.xtext.xbase.typesystem.internal.OptimizingFeatureScopeTrackerProvider'.typeRef)
bindFactory.addConfiguredBinding('LanguageSpecificPsiModelAssociations', '''
binder.bind(«"org.eclipse.xtext.psi.IPsiModelAssociations".typeRef».class)
.annotatedWith(«LanguageSpecific».class)
@ -111,7 +111,7 @@ class IdeaPluginGenerator extends AbstractXtextGeneratorFragment {
bindFactory.addTypeToType('org.eclipse.xtext.ide.editor.bracketmatching.IBracePairProvider'.typeRef, 'org.eclipse.xtext.xbase.idea.bracketmatching.XbaseBracePairProvider'.typeRef)
bindFactory.addTypeToType('org.eclipse.xtext.idea.findusages.IReferenceSearcher'.typeRef, 'org.eclipse.xtext.xbase.idea.findusages.JvmElementAwareReferenceSearcher'.typeRef)
bindFactory.addTypeToType('org.eclipse.xtext.xbase.compiler.IGeneratorConfigProvider'.typeRef, 'org.eclipse.xtext.xbase.idea.facet.XbaseGeneratorConfigProvider'.typeRef)
bindFactory.addTypeToType('org.eclipse.xtext.idea.findusages.WordsScannerProvider'.typeRef, 'org.eclipse.xtext.xbase.idea.findusages.XbaseWordsScanner.XbaseWordsScannerProvider'.typeRef)
bindFactory.addTypeToType('org.eclipse.xtext.idea.findusages.WordsScannerProvider'.typeRef, new TypeReference('org.eclipse.xtext.xbase.idea.findusages', 'XbaseWordsScanner.XbaseWordsScannerProvider'))
}
bindFactory.contributeTo(language.ideaGenModule)
@ -513,7 +513,7 @@ class IdeaPluginGenerator extends AbstractXtextGeneratorFragment {
def compileTokenTypeProvider(Grammar grammar) {
val tokenSet = "com.intellij.psi.tree.TokenSet".typeRef
val iElementType = "com.intellij.psi.tree.IElementType".typeRef
val indexedElementType = "org.eclipse.xtext.idea.parser.TokenTypeProvider.IndexedElementType".typeRef
val indexedElementType = new TypeReference("org.eclipse.xtext.idea.parser", "TokenTypeProvider.IndexedElementType")
return fileAccessFactory.createJavaFile(grammar.tokenTypeProvider, '''
@«Singleton» public class «grammar.tokenTypeProvider.simpleName» implements «"org.eclipse.xtext.idea.parser.TokenTypeProvider".typeRef» {

View file

@ -7,6 +7,7 @@
*******************************************************************************/
package org.eclipse.xtext.xtext.generator.model
import com.google.common.base.Splitter
import java.util.Collections
import java.util.List
import java.util.regex.Pattern
@ -15,8 +16,8 @@ import org.eclipse.emf.ecore.EPackage
import org.eclipse.emf.ecore.resource.ResourceSet
import org.eclipse.xtend.lib.annotations.Accessors
import org.eclipse.xtend.lib.annotations.EqualsHashCode
import org.eclipse.xtext.xtext.generator.util.GenModelUtil2
import org.eclipse.xtext.xtext.generator.IXtextGeneratorLanguage
import org.eclipse.xtext.xtext.generator.util.GenModelUtil2
@Accessors
@EqualsHashCode
@ -34,12 +35,8 @@ class TypeReference {
new TypeReference(clazz, language.resourceSet)
}
static def TypeReference typeRef(EPackage epackage, IXtextGeneratorLanguage language) {
new TypeReference(epackage, language.resourceSet)
}
static val PACKAGE_MATCHER = Pattern.compile('([a-z][a-zA-Z0-9_]*(\\.[a-z][a-zA-Z0-9_]*)*)?')
static val CLASS_MATCHER = Pattern.compile('[A-Z][a-zA-Z0-9_]*(\\.[A-Z][a-zA-Z0-9_]*)*')
static val PACKAGE_MATCHER = Pattern.compile('([a-zA-Z][a-zA-Z0-9_]*(\\.[a-zA-Z][a-zA-Z0-9_]*)*)?')
static val CLASS_MATCHER = Pattern.compile('[a-zA-Z][a-zA-Z0-9_]*(\\.[a-zA-Z][a-zA-Z0-9_]*)*')
val String packageName
@ -99,29 +96,21 @@ class TypeReference {
}
private static def getPackageName(String qualifiedName) {
var packageEnd = qualifiedName.length
for (var i = qualifiedName.length - 1; i >= 0; i--) {
if (qualifiedName.charAt(i).matches('.')) {
if (Character.isLowerCase(qualifiedName.charAt(i + 1)))
return qualifiedName.substring(0, packageEnd)
else
packageEnd = i
}
}
return ""
val segments = Splitter.on('.').split(qualifiedName).toList
if (segments.size == 1)
return ""
val packageSegments = segments.subList(0, segments.length -1)
if (!packageSegments.filter[Character.isUpperCase(charAt(0))].isEmpty)
throw new IllegalArgumentException("Cannot determine the package name of '" + qualifiedName + "'. Please use the TypeReference(packageName, className) constructor")
return packageSegments.join(".")
}
private static def getClassName(String qualifiedName) {
var classStart = qualifiedName.length
for (var i = qualifiedName.length - 1; i >= 0; i--) {
if (qualifiedName.charAt(i).matches('.')) {
if (Character.isLowerCase(qualifiedName.charAt(i + 1)))
return qualifiedName.substring(classStart)
else
classStart = i + 1
}
}
return qualifiedName
val packageName = qualifiedName.packageName
if (packageName.isEmpty)
qualifiedName
else
qualifiedName.substring(packageName.length + 1, qualifiedName.length)
}
private static def getQualifiedName(EClass clazz, ResourceSet resourceSet) {
@ -135,10 +124,6 @@ class TypeReference {
GenModelUtil2.getGenPackage(epackage, resourceSet).qualifiedPackageInterfaceName
}
private static def matches(char c1, char c2) {
c1 == c2
}
override toString() {
name + typeArguments.join('<', ', ', '>', [toString])
}

View file

@ -49,6 +49,7 @@ import static extension org.eclipse.xtext.GrammarUtil.*
import static extension org.eclipse.xtext.xtext.generator.model.TypeReference.*
import static extension org.eclipse.xtext.xtext.generator.parser.antlr.AntlrGrammarGenUtil.*
import org.eclipse.xtext.xtext.generator.util.SyntheticTerminalDetector
import org.eclipse.xtext.xtext.generator.model.TypeReference
class XtextAntlrGeneratorFragment2 extends AbstractAntlrGeneratorFragment2 {
@Accessors
@ -487,7 +488,7 @@ class XtextAntlrGeneratorFragment2 extends AbstractAntlrGeneratorFragment2 {
.to(«AntlrTokenDefProvider».class);
''')
.addTypeToType(
"org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext.Factory".typeRef,
new TypeReference("org.eclipse.xtext.ui.editor.contentassist", "ContentAssistContext.Factory"),
"org.eclipse.xtext.ui.editor.contentassist.antlr.DelegatingContentAssistContextFactory".typeRef
)
.addTypeToType(

View file

@ -417,7 +417,7 @@ class SerializerFragment2 extends AbstractStubGeneratingFragment {
protected «grammar.grammarAccess» grammarAccess;
«FOR group : allAmbiguousTransitionsBySyntax»
protected «'org.eclipse.xtext.serializer.analysis.GrammarAlias.AbstractElementAlias'.typeRef» match_«group.identifier»;
protected «new TypeReference ('org.eclipse.xtext.serializer.analysis', 'GrammarAlias.AbstractElementAlias')» match_«group.identifier»;
«ENDFOR»
@«Inject»

View file

@ -18,6 +18,7 @@ import org.eclipse.xtext.xtext.generator.xbase.XbaseUsageDetector
import static extension org.eclipse.xtext.GrammarUtil.*
import static extension org.eclipse.xtext.xtext.generator.model.TypeReference.*
import org.eclipse.xtext.xtext.generator.AbstractXtextGeneratorFragment
import org.eclipse.xtext.xtext.generator.model.TypeReference
/**
* Contributes the registration of element renaming infrastructure.
@ -60,11 +61,9 @@ class RefactorElementNameFragment2 extends AbstractXtextGeneratorFragment {
.addConfiguredBinding(
"org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreInitializer".typeRef.simpleNames.join("."),
'''
binder.bind(«
"org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreInitializer".typeRef
».class).annotatedWith(«Names».named("RefactoringPreferences")).to(«
"org.eclipse.xtext.ui.refactoring.ui.RefactoringPreferences.Initializer".typeRef
».class);
binder.bind(«"org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreInitializer".typeRef».class)
.annotatedWith(«Names».named("RefactoringPreferences"))
.to(«new TypeReference("org.eclipse.xtext.ui.refactoring.ui", "RefactoringPreferences.Initializer")».class);
''')
if (grammar.useJdtRefactoring) {
@ -78,19 +77,19 @@ class RefactorElementNameFragment2 extends AbstractXtextGeneratorFragment {
"org.eclipse.xtext.common.types.ui.refactoring.JvmRenameRefactoringProvider".typeRef)
.addTypeToType(
"org.eclipse.xtext.ui.refactoring.ui.IRenameSupport.Factory".typeRef,
"org.eclipse.xtext.common.types.ui.refactoring.JdtRenameSupport.Factory".typeRef)
new TypeReference("org.eclipse.xtext.ui.refactoring.ui", "IRenameSupport.Factory"),
new TypeReference("org.eclipse.xtext.common.types.ui.refactoring", "JdtRenameSupport.Factory"))
.addTypeToType(
"org.eclipse.xtext.ui.refactoring.IRenameStrategy.Provider".typeRef,
"org.eclipse.xtext.common.types.ui.refactoring.participant.JvmMemberRenameStrategy.Provider".typeRef)
new TypeReference("org.eclipse.xtext.ui.refactoring", "IRenameStrategy.Provider"),
new TypeReference("org.eclipse.xtext.common.types.ui.refactoring.participant", "JvmMemberRenameStrategy.Provider"))
.addConfiguredBinding(
"org.eclipse.xtext.common.types.ui.refactoring.participant.JvmMemberRenameStrategy.Provider.Delegate".typeRef.simpleNames.join("."),
"JvmMemberRenameStrategy.Provider.Delegate",
'''
binder.bind(«"org.eclipse.xtext.ui.refactoring.IRenameStrategy.Provider".typeRef
binder.bind(«new TypeReference("org.eclipse.xtext.ui.refactoring", "IRenameStrategy.Provider")
».class).annotatedWith(«
"org.eclipse.xtext.common.types.ui.refactoring.participant.JvmMemberRenameStrategy.Provider.Delegate".typeRef
new TypeReference("org.eclipse.xtext.common.types.ui.refactoring.participant", "JvmMemberRenameStrategy.Provider.Delegate")
».class).to(«"org.eclipse.xtext.ui.refactoring.impl.DefaultRenameStrategyProvider".typeRef
».class);
''')
@ -101,8 +100,8 @@ class RefactorElementNameFragment2 extends AbstractXtextGeneratorFragment {
"org.eclipse.xtext.ui.refactoring.impl.DefaultRenameRefactoringProvider".typeRef)
.addTypeToType(
"org.eclipse.xtext.ui.refactoring.ui.IRenameSupport.Factory".typeRef,
"org.eclipse.xtext.ui.refactoring.ui.DefaultRenameSupport.Factory".typeRef)
new TypeReference("org.eclipse.xtext.ui.refactoring.ui", "IRenameSupport.Factory"),
new TypeReference("org.eclipse.xtext.ui.refactoring.ui", "DefaultRenameSupport.Factory"))
}
bindings.contributeTo(language.eclipsePluginGenModule);

View file

@ -146,8 +146,8 @@ class XbaseGeneratorFragment2 extends AbstractXtextGeneratorFragment {
.addTypeToType('org.eclipse.xtext.ui.refactoring.IRenameStrategy'.typeRef,
'org.eclipse.xtext.xbase.ui.jvmmodel.refactoring.DefaultJvmModelRenameStrategy'.typeRef)
.addTypeToType('org.eclipse.xtext.common.types.ui.refactoring.participant.JdtRenameParticipant.ContextFactory'.typeRef,
'org.eclipse.xtext.xbase.ui.jvmmodel.refactoring.JvmModelJdtRenameParticipantContext.ContextFactory'.typeRef)
.addTypeToType(new TypeReference('org.eclipse.xtext.common.types.ui.refactoring.participant', 'JdtRenameParticipant.ContextFactory'),
new TypeReference ('org.eclipse.xtext.xbase.ui.jvmmodel.refactoring', 'JvmModelJdtRenameParticipantContext.ContextFactory'))
.addTypeToType('org.eclipse.xtext.ui.editor.outline.impl.OutlineNodeElementOpener'.typeRef,
'org.eclipse.xtext.xbase.ui.jvmmodel.outline.JvmOutlineNodeElementOpener'.typeRef)
.addTypeToType('org.eclipse.xtext.ui.editor.GlobalURIEditorOpener'.typeRef,
@ -155,7 +155,7 @@ class XbaseGeneratorFragment2 extends AbstractXtextGeneratorFragment {
.addTypeToType('org.eclipse.xtext.ui.editor.occurrences.IOccurrenceComputer'.typeRef,
'org.eclipse.xtext.xbase.ui.jvmmodel.occurrence.JvmModelOccurrenceComputer'.typeRef)
.addTypeToType('org.eclipse.xtext.common.types.ui.query.IJavaSearchParticipation'.typeRef,
'org.eclipse.xtext.common.types.ui.query.IJavaSearchParticipation.No'.typeRef)
new TypeReference('org.eclipse.xtext.common.types.ui.query', 'IJavaSearchParticipation.No'))
// DerivedMemberAwareEditorOpener
.addConfiguredBinding('LanguageSpecificURIEditorOpener', statement)
} else {

View file

@ -7,6 +7,7 @@
*******************************************************************************/
package org.eclipse.xtext.generator
import org.eclipse.xtext.xtext.generator.model.TypeReference
import org.junit.Test
import static org.junit.Assert.*
@ -40,14 +41,27 @@ class TypeReferenceTest {
assertEquals("String", ref.typeArguments.head.simpleName)
}
@Test(expected = IllegalArgumentException)
def void testWrongNestedTypeUsage() {
"java.util.Map.Entry".typeRef
}
@Test
def void testNestedType() {
val ref = "java.util.Map.Entry".typeRef
val ref = new TypeReference("java.util", "Map.Entry")
assertEquals("java.util", ref.packageName)
assertEquals("Entry", ref.simpleName)
assertEquals(#["Map", "Entry"], ref.simpleNames)
}
@Test
def void testLowerCaseNestedType() {
val ref = new TypeReference("java.util", "Map.entry")
assertEquals("java.util", ref.packageName)
assertEquals("entry", ref.simpleName)
assertEquals(#["Map", "entry"], ref.simpleNames)
}
@Test
def void testJavaPath() {
val ref = "org.example.MyType".typeRef