Skip to content

Commit

Permalink
Merge fa6acc1 into 7d4d764
Browse files Browse the repository at this point in the history
  • Loading branch information
fdodino committed Aug 14, 2018
2 parents 7d4d764 + fa6acc1 commit 5025148
Show file tree
Hide file tree
Showing 12 changed files with 227 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import org.eclipse.ui.IPartListener
import org.eclipse.ui.IWorkbenchPart
import org.eclipse.ui.views.contentoutline.ContentOutline
import org.eclipse.xtend.lib.annotations.Accessors
import org.eclipse.xtext.documentation.impl.MultiLineCommentDocumentationProvider
import org.eclipse.xtext.ui.editor.IURIEditorOpener
import org.eclipse.xtext.ui.editor.outline.impl.OutlinePage
import org.eclipse.xtext.ui.editor.quickfix.IssueResolutionProvider
Expand Down Expand Up @@ -54,6 +55,9 @@ class WollokActivator extends org.uqbar.project.wollok.ui.internal.WollokActivat
@Accessors @Inject
IssueResolutionProvider issueResolutionProvider

@Accessors @Inject
MultiLineCommentDocumentationProvider multilineProvider

Map<String, List<Issue>> mapIssues = new HashMap

def static WollokActivator getInstance() {
Expand Down Expand Up @@ -109,7 +113,7 @@ class WollokActivator extends org.uqbar.project.wollok.ui.internal.WollokActivat

def void refreshOutline() {
Display.^default.syncExec [
val outlineView = activePage.findView("org.eclipse.ui.views.ContentOutline") as ContentOutline
val outlineView = activePage?.findView("org.eclipse.ui.views.ContentOutline") as ContentOutline
if (outlineView !== null) {
val outlinePage = outlineView.currentPage
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.uqbar.project.wollok.ui.contentassist

import org.eclipse.jface.text.contentassist.ICompletionProposal
import org.eclipse.xtext.ui.editor.contentassist.ConfigurableCompletionProposal
import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor

import static extension org.uqbar.project.wollok.utils.ProposalUtils.*

class ConstructorCallAcceptorDelegate extends ICompletionProposalAcceptor.Delegate {

new(ICompletionProposalAcceptor acceptor) {
super(acceptor)
}

override accept(ICompletionProposal originalProposal) {
super.accept(originalProposal?.enhance)
}

def dispatch ICompletionProposal enhance(ICompletionProposal proposal) {
proposal
}

def dispatch ICompletionProposal enhance(ConfigurableCompletionProposal proposal) {
if (proposal !== null && proposal.replacementString !== null) {
proposal.replacementString = proposal.className + "()"
}
proposal
}

override canAcceptMoreProposals() {
true
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,28 @@ package org.uqbar.project.wollok.ui.contentassist

import org.eclipse.emf.ecore.EObject
import org.eclipse.xtext.Assignment
import org.eclipse.xtext.CrossReference
import org.eclipse.xtext.RuleCall
import org.eclipse.xtext.naming.QualifiedName
import org.eclipse.xtext.ui.editor.contentassist.ConfigurableCompletionProposal
import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext
import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor
import org.uqbar.project.wollok.interpreter.WollokClassFinder
import org.uqbar.project.wollok.ui.Messages
import org.uqbar.project.wollok.ui.WollokActivator
import org.uqbar.project.wollok.wollokDsl.WBooleanLiteral
import org.uqbar.project.wollok.wollokDsl.WClosure
import org.uqbar.project.wollok.wollokDsl.WConstructorCall
import org.uqbar.project.wollok.wollokDsl.WExpression
import org.uqbar.project.wollok.wollokDsl.WLibraryElement
import org.uqbar.project.wollok.wollokDsl.WMember
import org.uqbar.project.wollok.wollokDsl.WListLiteral
import org.uqbar.project.wollok.wollokDsl.WMemberFeatureCall
import org.uqbar.project.wollok.wollokDsl.WMethodContainer
import org.uqbar.project.wollok.wollokDsl.WNamedObject
import org.uqbar.project.wollok.wollokDsl.WNumberLiteral
import org.uqbar.project.wollok.wollokDsl.WReferenciable
import org.uqbar.project.wollok.wollokDsl.WSelf
import org.uqbar.project.wollok.wollokDsl.WSetLiteral
import org.uqbar.project.wollok.wollokDsl.WStringLiteral
import org.uqbar.project.wollok.wollokDsl.WVariable
import org.uqbar.project.wollok.wollokDsl.WVariableReference

Expand All @@ -26,11 +34,15 @@ import static extension org.uqbar.project.wollok.model.WollokModelExtensions.*
/**
*
* @author jfernandes
* @see https://www.eclipse.org/Xtext/documentation/310_eclipse_support.html#content-assist
*
*/
class WollokDslProposalProvider extends AbstractWollokDslProposalProvider {
var extension BasicTypeResolver typeResolver = new BasicTypeResolver
val extension BasicTypeResolver typeResolver = new BasicTypeResolver
val extension WollokClassFinder classFinder = WollokClassFinder.getInstance

WollokProposalBuilder builder

override complete_WConstructorCall(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
if (model instanceof WConstructorCall) {
val initializations = (model as WConstructorCall).createInitializersForNamedParametersInConstructor
Expand All @@ -54,6 +66,31 @@ class WollokDslProposalProvider extends AbstractWollokDslProposalProvider {
def dispatch void memberProposalsForTarget(WExpression expression, Assignment assignment, ICompletionProposalAcceptor acceptor) {
}

// literals
def dispatch void memberProposalsForTarget(WListLiteral expression, Assignment assignment, ICompletionProposalAcceptor acceptor) {
(expression.listClass as WMethodContainer).methodsAsProposals(acceptor)
}

def dispatch void memberProposalsForTarget(WSetLiteral expression, Assignment assignment, ICompletionProposalAcceptor acceptor) {
(expression.setClass as WMethodContainer).methodsAsProposals(acceptor)
}

def dispatch void memberProposalsForTarget(WBooleanLiteral expression, Assignment assignment, ICompletionProposalAcceptor acceptor) {
(expression.booleanClass as WMethodContainer).methodsAsProposals(acceptor)
}

def dispatch void memberProposalsForTarget(WClosure expression, Assignment assignment, ICompletionProposalAcceptor acceptor) {
(expression.closureClass as WMethodContainer).methodsAsProposals(acceptor)
}

def dispatch void memberProposalsForTarget(WStringLiteral expression, Assignment assignment, ICompletionProposalAcceptor acceptor) {
(expression.stringClass as WMethodContainer).methodsAsProposals(acceptor)
}

def dispatch void memberProposalsForTarget(WNumberLiteral expression, Assignment assignment, ICompletionProposalAcceptor acceptor) {
(expression.numberClass as WMethodContainer).methodsAsProposals(acceptor)
}

// to a variable
def dispatch void memberProposalsForTarget(WVariableReference ref, Assignment assignment, ICompletionProposalAcceptor acceptor) {
memberProposalsForTarget(ref.ref, assignment, acceptor)
Expand All @@ -68,10 +105,10 @@ class WollokDslProposalProvider extends AbstractWollokDslProposalProvider {
def dispatch void memberProposalsForTarget(WVariable ref, Assignment assignment, ICompletionProposalAcceptor acceptor) {
val WMethodContainer type = ref.resolveType
if (type !== null) {
type.methodsAsProposals( acceptor)
type.methodsAsProposals(acceptor)
}
else {
ref.messageSentAsProposals( acceptor)
ref.messageSentAsProposals(acceptor)
}
}

Expand All @@ -98,38 +135,53 @@ class WollokDslProposalProvider extends AbstractWollokDslProposalProvider {
def methodsAsProposals(WMethodContainer ref, ICompletionProposalAcceptor acceptor) {
builder.model = ref
builder.reference = ref.nameWithPackage
ref.allMethods.forEach[ addProposal( it, acceptor) ]
// @Dodain - kind of hack to retrieve getters and setters from properties
builder.accessorKind = Accessor.GETTER
ref.allPropertiesGetters.forEach [ addProposal(it, acceptor) ]
builder.accessorKind = Accessor.SETTER
ref.allPropertiesSetters.forEach [ addProposal(it, acceptor) ]
builder.accessorKind = Accessor.NONE
ref.allMethods.forEach[ addProposal(it, acceptor) ]
}

def addProposal(WMember m, ICompletionProposalAcceptor acceptor) {
builder.member = m
def addProposal(EObject o, ICompletionProposalAcceptor acceptor) {
builder.member = o
builder.assignPriority
acceptor.addProposal(builder.proposal)
}


// *****************************
// ** generic extension methods
// *****************************

def addProposal(ICompletionProposalAcceptor acceptor, WollokProposal aProposal) {
if (aProposal !== null) acceptor.accept(createCompletionProposal(aProposal.methodName, aProposal.displayMessage, aProposal.image, aProposal.priority, "", aProposal.context))
if (aProposal === null) return;
val proposal = createCompletionProposal(aProposal.methodName, aProposal.displayMessage, aProposal.image, aProposal.priority, aProposal.prefix, aProposal.context)
acceptor.accept(proposal)
if (proposal instanceof ConfigurableCompletionProposal) {
proposal.additionalProposalInfo = WollokActivator.getInstance.multilineProvider.getDocumentation(aProposal.member)
}
}

// ****************************************
// ** imports
// ****************************************

override completeImport_ImportedNamespace(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
val content = model.file.resourceSet.allContents.filter(WLibraryElement)
val alreadyImported = model.file.importedDefinitions
val content = model.file.allPossibleImports.filter [ element |
val containerFqn = element.fqn
val containerQn = QualifiedName.create(containerFqn.split("\\."))
alreadyImported.forall [ deresolve(containerQn) === null ]
]
// add other files content here

content.forEach[
if (it instanceof WMethodContainer)
acceptor.accept(createCompletionProposal(fqn, fqn, image, context))
acceptor.accept(createCompletionProposal(fqn, fqn, image, context))
]
}

//@Inject
//@Inject
//protected WollokDslTypeSystem system
//
// def dispatch void memberProposalsForTarget(WVariableReference reference, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
Expand All @@ -156,4 +208,8 @@ class WollokDslProposalProvider extends AbstractWollokDslProposalProvider {
}
*/

override completeWConstructorCall_ClassRef(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
lookupCrossReference((assignment.terminal as CrossReference), context, new ConstructorCallAcceptorDelegate(acceptor))
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,38 @@ import org.uqbar.project.wollok.ui.Messages
import org.uqbar.project.wollok.wollokDsl.WBooleanLiteral
import org.uqbar.project.wollok.wollokDsl.WClosure
import org.uqbar.project.wollok.wollokDsl.WCollectionLiteral
import org.uqbar.project.wollok.wollokDsl.WConstructor
import org.uqbar.project.wollok.wollokDsl.WConstructorCall
import org.uqbar.project.wollok.wollokDsl.WExpression
import org.uqbar.project.wollok.wollokDsl.WMember
import org.uqbar.project.wollok.wollokDsl.WMemberFeatureCall
import org.uqbar.project.wollok.wollokDsl.WMethodContainer
import org.uqbar.project.wollok.wollokDsl.WMethodDeclaration
import org.uqbar.project.wollok.wollokDsl.WNullLiteral
import org.uqbar.project.wollok.wollokDsl.WNumberLiteral
import org.uqbar.project.wollok.wollokDsl.WObjectLiteral
import org.uqbar.project.wollok.wollokDsl.WSelf
import org.uqbar.project.wollok.wollokDsl.WStringLiteral
import org.uqbar.project.wollok.wollokDsl.WVariable
import org.uqbar.project.wollok.wollokDsl.WVariableDeclaration
import org.uqbar.project.wollok.wollokDsl.WVariableReference

import static extension org.uqbar.project.wollok.model.WMethodContainerExtensions.*
import static extension org.uqbar.project.wollok.model.WollokModelExtensions.*

enum Accessor {
NONE, GETTER, SETTER
}

@Accessors
class WollokProposal {
String referencePackage
EObject model
WMember member
EObject member
Image image
int priority = 0
ContentAssistContext context
boolean isCalledFromSelf
Accessor accessor

new(String reference, WMember m, Image image, int priority, ContentAssistContext context, EObject model) {
new(String reference, EObject m, Image image, int priority, ContentAssistContext context, EObject model) {
this.referencePackage = reference
this.member = m
this.image = image
Expand All @@ -50,20 +54,28 @@ class WollokProposal {
this.model = model
}

def getPrefix() {
context.prefix
}

def getMethodName() {
member.asProposal
}

def getContainer() {
member.eContainer as WMethodContainer
}

def getContainerName() {
member.getMethodContainer.name
container.name
}

def getContainerPackage() {
member.getMethodContainer.packageName
container.packageName
}

def getContainerFqn() {
member.getMethodContainer.getNameWithPackage
container.nameWithPackage
}

def createProposalStyler() {
Expand Down Expand Up @@ -105,6 +117,19 @@ class WollokProposal {
if(member !== null && member.declaringContext !== null) member.declaringContext.name + "." else ""
}

def dispatch asProposal(EObject o) { throw new IllegalArgumentException("Node " + o + " should not be a proposal") }

// it is a property
def dispatch asProposal(WVariableDeclaration v) {
v.variable.name + v.suffix
}

def suffix(WVariableDeclaration v) {
if (!v.property) return ""
if (accessor == Accessor.GETTER) return "()"
if (accessor == Accessor.SETTER) "(value)" else ""
}

def dispatch asProposal(WMemberFeatureCall call) {
call.feature + "(" + call.memberCallArguments.map[asProposalParameter].join(",") + ")"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext
import org.uqbar.project.wollok.interpreter.WollokRuntimeException
import org.uqbar.project.wollok.ui.Messages
import org.uqbar.project.wollok.ui.WollokActivator
import org.uqbar.project.wollok.wollokDsl.WMember
import org.uqbar.project.wollok.wollokDsl.WMethodContainer

import static extension org.uqbar.project.wollok.model.WMethodContainerExtensions.*
Expand All @@ -16,18 +15,20 @@ import static extension org.uqbar.project.wollok.model.WMethodContainerExtension
class WollokProposalBuilder {
boolean displayFullFqn = false
String reference
WMember member
EObject member
EObject model
int priority
List<WMethodContainer> classHierarchy = newArrayList
static String imagePath = 'icons/wollok-icon-method_16.png'
ContentAssistContext context
Accessor accessorKind

def getProposal() {
this.validate()
var WollokProposal result = new WollokProposal(reference, member, WollokActivator.getInstance.getImageDescriptor(imagePath).createImage, priority, context, model)
result.isCalledFromSelf = displayFullFqn
result
new WollokProposal(reference, member, WollokActivator.getInstance.getImageDescriptor(imagePath).createImage, priority, context, model) => [
isCalledFromSelf = displayFullFqn
accessor = accessorKind
]
}

def private validate() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class WollokDslLabelProvider extends DefaultEObjectLabelProvider {
def image(WProgram it) { 'wollok-icon-program_16.png' }

def image(WClass it) { 'wollok-icon-class_16.png' }

def image(WMixin it) { 'wollok-icon-mixin_16.png' }

def image(WTest it) { 'wollok-icon-test_16.png' }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,18 @@ class WMethodContainerExtensions extends WollokModelExtensions {
allVariableDeclarations.map [ variable ]
}

def static allProperties(WMethodContainer it) {
allVariableDeclarations.filter [ property ]
}

def static allPropertiesGetters(WMethodContainer it) {
allProperties
}

def static allPropertiesSetters(WMethodContainer it) {
allProperties.filter [ writeable ]
}

def static getInheritedMethods(WMethodContainer it) {
linearizeHierarchy.fold(newArrayList) [methods, type |
val currents = type.methods
Expand Down
Loading

0 comments on commit 5025148

Please sign in to comment.