[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [pdt-dev] Extending PDT: type inference questions

hi,

if you only want to content assist for ClassRegistry::init(B)-> you could follow http://wiki.eclipse.org/Extending_PDT_2.2#Code_assist_strategies then call context via
getStatementText() and parse this text manually in class XYZCompletionStrategy(extends ClassMembersStrategy),instead of call context.getLhsTypes().

for example you could use the following code in XYZCompletionStrategy#apply:


ÂÂÂ public void apply(ICompletionReporter reporter) throws BadLocationException {
ÂÂÂ ÂÂÂ ICompletionContext context = getContext();
ÂÂÂ ÂÂÂ if (!(context instanceof ClassMemberContext)) {
ÂÂÂ ÂÂÂ ÂÂÂ return;
ÂÂÂ ÂÂÂ }

ÂÂÂ ÂÂÂ ClassMemberContext concreteContext = (ClassMemberContext) context;
ÂÂÂ ÂÂÂ CompletionRequestor requestor = concreteContext
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ .getCompletionRequestor();

ÂÂÂ ÂÂÂ String prefix = concreteContext.getPrefix();
ÂÂÂ ÂÂÂ boolean isParentCall = isParentCall(concreteContext);
ÂÂÂ ÂÂÂ String suffix = getSuffix(concreteContext);

ÂÂÂ ÂÂÂ SourceRange replaceRange = null;
ÂÂÂ ÂÂÂ if (suffix.equals("")) {
ÂÂÂ ÂÂÂ ÂÂÂ replaceRange = getReplacementRange(concreteContext);
ÂÂÂ ÂÂÂ } else {
ÂÂÂ ÂÂÂ ÂÂÂ replaceRange = getReplacementRangeWithBraces(concreteContext);
ÂÂÂ ÂÂÂ }

ÂÂÂ ÂÂÂ PHPVersion phpVersion = concreteContext.getPhpVersion();
ÂÂÂ ÂÂÂ Set<String> magicMethods = new HashSet<String>();
ÂÂÂ ÂÂÂ magicMethods.addAll(Arrays.asList(PHPMagicMethods
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ .getMethods(phpVersion)));

ÂÂÂ ÂÂÂ boolean exactName = requestor.isContextInformationMode();
ÂÂÂ ÂÂÂ List<IMethod> result = new LinkedList<IMethod>();
ÂÂÂ ÂÂÂ ISourceModuleContext sourceModuleContext = new FileContext(
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ concreteContext.getSourceModule(),
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ SourceParserUtil.getModuleDeclaration(concreteContext
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ .getSourceModule()));
ÂÂÂ ÂÂÂ String textSequence = concreteContext.getStatementText().toString();
ÂÂÂ ÂÂÂ if (textSequence.indexOf("ClassRegistry::init(") >= 0) {
ÂÂÂ ÂÂÂ ÂÂÂ textSequence = textSequence.substring(textSequence
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ .indexOf("ClassRegistry::init(")
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ + "ClassRegistry::init(".length());
ÂÂÂ ÂÂÂ ÂÂÂ textSequence = textSequence.substring(0, textSequence
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ .lastIndexOf(")->"));
ÂÂÂ ÂÂÂ ÂÂÂ String className = textSequence.substring(1,
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ textSequence.length() - 1);
ÂÂÂ ÂÂÂ ÂÂÂ IType[] types = PHPTypeInferenceUtils.getModelElements(
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ new PHPClassType(className), sourceModuleContext,
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ concreteContext.getOffset());
ÂÂÂ ÂÂÂ ÂÂÂ for (IType type : types) {
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ try {
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ITypeHierarchy hierarchy = getCompanion()
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ .getSuperTypeHierarchy(type, null);

ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ IMethod[] methods = isParentCall ? PHPModelUtils
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ .getSuperTypeHierarchyMethod(type, hierarchy,
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ prefix, exactName, null) : PHPModelUtils
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ .getTypeHierarchyMethod(type, hierarchy, prefix,
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ exactName, null);

ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ boolean inConstructor = isInConstructor(type, type
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ .getMethods(), concreteContext);
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ for (IMethod method : removeOverriddenElements(Arrays
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ .asList(methods))) {

ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ if ((!isConstructor(method) || inConstructor
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ && isSuperConstructor(method, type,
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ concreteContext))
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ && !isFiltered(method, type, concreteContext)) {
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ if (magicMethods.contains(method.getElementName())) {
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ reporter.reportMethod(method, suffix,
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ replaceRange,
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ProposalExtraInfo.MAGIC_METHOD);
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ } else {
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ result.add(method);
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ }
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ }
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ }
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ } catch (CoreException e) {
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ PHPCorePlugin.log(e);
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ }
ÂÂÂ ÂÂÂ ÂÂÂ }
ÂÂÂ ÂÂÂ ÂÂÂ for (IMethod method : result) {
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ reporter.reportMethod((IMethod) method, suffix, replaceRange);
ÂÂÂ ÂÂÂ ÂÂÂ }
ÂÂÂ ÂÂÂ }

ÂÂÂ }

of course the above code is just an example,you need make some changes


to make ctrl+click and hover on method bbb(ClassRegistry::init('B')->bbb()) work,you still need class XYZGoalEvaluatorFactory.

Hope this works for you:)

On Fri, Dec 31, 2010 at 10:41 PM, Kooper <victor.kupriyanov@xxxxxxxxx> wrote:
Hello,

It is really simple - here it is:

<?php

class ClassRegistry {
   Âpublic static function init($classname) {
       Â$a = new $classname();

       Âif ($a) {
           Âreturn $a;
       Â}

       Âreturn null;
   Â}
}

class A {
   Âpublic function aaa() { echo "A"; }
}

class B {
   Âpublic function bbb() { echo "B"; }
}

ClassRegistry::init(B)->


I'm not using quotes around class name in method call currently (it is
because of quotes are included in value of classname in GoalEvaluator
- just didn't handle this yet)

--
Victor Kupriyanov

On Thu, Dec 30, 2010 at 4:00 PM, Roy Ganor <roy@xxxxxxxx> wrote:
> Hi Victor,
>
> Can you provide a code snippet of your ClassRegistry class? Including the "init" static method.
>
> Thanks,
> Roy
> -----Original Message-----
> From: pdt-dev-bounces@xxxxxxxxxxx [mailto:pdt-dev-bounces@xxxxxxxxxxx] On Behalf Of Kooper
> Sent: Wednesday, December 29, 2010 12:55 PM
> To: pdt-dev@xxxxxxxxxxx
> Subject: [pdt-dev] Extending PDT: type inference questions
>
> Hello,
>
> I'm trying to write a custom extension to PDT 2.2 that adds code assistance for
> object instantiation for particular framework. I'm following the guidelines at
> http://wiki.eclipse.org/Extending_PDT_2.2#Type_inference_hinting and have a
> working code for exactly the case from the article:
>
> $myObject = ClassRegistry::init('MyClass');
> $myObject->... // A list of methods of MyClass is shown ok
>
> However it seems like the same type inference approach does not work when
> not using variable assignment:
>
> ClassRegistry::init('MyClass')->... // No proposals available
>
> Tracing goals evaluation factory for the latter case I found that this
> code snippet does not bring up evaluation of any ExpressionTypeGoal goals for
> context of the call, but starts with evaluation of MethodElementReturnTypeGoal
> that later leads to evaluation of method 'ClassRegistry::init's code.
>
> Attempting to implement evaluation of MethodElementReturnTypeGoal I was
> unable to access call context and actual arguments' values. Neither I
> succeeded in attempts to obtain MethodReturnTypeGoal object (which has
> getArguments() method)
>
>
> I also tried to utilize code assist strategy via ClassMemberContext. At
> first glance it looked promising. However I was unable to find out reciever
> class for '->' operator, as ClassMemberContext.getLhsTypes() returns empty
> list for the example above.
>
> Albeit I'm actually have access to call context with ClassMemberContext, I'm
> not happy with it - as it provides only text of call context via
> getStatementText() and it turns out that I have to parse this text manually.
>
> * So, can anybody help me by pointing directions that I should dig further?
> * Is there an access from MethodElementReturnTypeGoal to call context or actual
> call arguments?
> * Why there is no attempt to evaluate goal for call context prior to
> goal for method's content?
> * Is there a way to access goal evaluator from ClassMemberContext?
> * Do I have a broken installation or facing a known bug?
>
>
> Thank you in advance.
>
> --
> Victor Kupriyanov
> _______________________________________________
> pdt-dev mailing list
> pdt-dev@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/pdt-dev
> _______________________________________________
> pdt-dev mailing list
> pdt-dev@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/pdt-dev
>
_______________________________________________
pdt-dev mailing list
pdt-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/pdt-dev



--

Thanks!

Best Regards!

Zhao