示例#1
0
  public RawMethod(final MethodReference baseMethod) {
    VerifyArgument.notNull(baseMethod, "baseMethod");

    final TypeReference declaringType = baseMethod.getDeclaringType();

    _baseMethod = baseMethod;
    _declaringType = MetadataHelper.eraseRecursive(declaringType);
    _returnType = MetadataHelper.eraseRecursive(baseMethod.getReturnType());
    _parameters = new ParameterDefinitionCollection(this);

    for (final ParameterDefinition parameter : baseMethod.getParameters()) {
      if (parameter.hasName()) {
        _parameters.add(
            new ParameterDefinition(
                parameter.getSlot(),
                parameter.getName(),
                MetadataHelper.eraseRecursive(parameter.getParameterType())));
      } else {
        _parameters.add(
            new ParameterDefinition(
                parameter.getSlot(), MetadataHelper.eraseRecursive(parameter.getParameterType())));
      }
    }

    _parameters.freeze();
  }
  public static PsiElement findArrayKeyValueInsideReference(
      PsiElement psiElement, String methodReferenceName, String keyName) {

    if (psiElement == null) {
      return null;
    }

    Collection<MethodReference> tests =
        PsiTreeUtil.findChildrenOfType(psiElement, MethodReference.class);
    for (MethodReference methodReference : tests) {

      // instance check
      // methodReference.getSignature().equals("#M#C\\Symfony\\Component\\OptionsResolver\\OptionsResolverInterface.setDefaults")
      if (PhpElementsUtil.isEqualMethodReferenceName(methodReference, methodReferenceName)) {
        PsiElement[] parameters = methodReference.getParameters();
        if (parameters.length > 0 && parameters[0] instanceof ArrayCreationExpression) {
          PsiElement keyValue =
              PhpElementsUtil.getArrayValue((ArrayCreationExpression) parameters[0], keyName);
          if (keyValue != null) {
            return keyValue;
          }
        }
      }
    }

    return null;
  }
  @Override
  public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef)
      throws IOException {
    ClassReader cls = context.getClassSource().get(methodRef.getClassName());
    MethodReader method = cls.getMethod(methodRef.getDescriptor());
    AnnotationReader providerAnnot = method.getAnnotations().get(MetadataProvider.class.getName());

    AnnotationReader refAnnot = method.getAnnotations().get(MetadataProviderRef.class.getName());
    methodRef = MethodReference.parse(refAnnot.getValue("value").getString());

    // Find and instantiate metadata generator
    ValueType generatorType = providerAnnot.getValue("value").getJavaClass();
    String generatorClassName = ((ValueType.Object) generatorType).getClassName();
    Class<?> generatorClass;
    try {
      generatorClass = Class.forName(generatorClassName, true, context.getClassLoader());
    } catch (ClassNotFoundException e) {
      context
          .getDiagnostics()
          .error(
              new CallLocation(methodRef),
              "Can't find metadata provider class {{c0}}",
              generatorClassName);
      return;
    }
    Constructor<?> cons;
    try {
      cons = generatorClass.getConstructor();
    } catch (NoSuchMethodException e) {
      context
          .getDiagnostics()
          .error(
              new CallLocation(methodRef),
              "Metadata generator {{c0}} does not have " + "a public no-arg constructor",
              generatorClassName);
      return;
    }
    MetadataGenerator generator;
    try {
      generator = (MetadataGenerator) cons.newInstance();
    } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
      context
          .getDiagnostics()
          .error(
              new CallLocation(methodRef),
              "Error instantiating metadata " + "generator {{c0}}",
              generatorClassName);
      return;
    }
    DefaultMetadataGeneratorContext metadataContext =
        new DefaultMetadataGeneratorContext(
            context.getClassSource(), context.getClassLoader(), context.getProperties(), context);

    // Generate resource loader
    Resource resource = generator.generateMetadata(metadataContext, methodRef);
    writer.append("return ");
    ResourceWriterHelper.write(writer, resource);
    writer.append(';').softNewLine();
  }
  @Nullable
  public static PsiElement getMethodParameterPsiElementAt(
      @Nullable MethodReference methodReference, int index) {

    if (methodReference == null) {
      return null;
    }

    return getMethodParameterPsiElementAt(methodReference.getParameterList(), index);
  }
示例#5
0
 /** Find the value for an annotation */
 private Object getElementValue(String name, Class<?> valueType) {
   for (AnnotationMember evp : elementValuePairs) {
     String evpFieldName = evp.getName().toString();
     if (name.equals(evpFieldName)) {
       return evp.getValue();
     }
   }
   MethodReference methRef =
       MemberReference.findOrCreate(
               type,
               Atom.findOrCreateAsciiAtom(name),
               Atom.findOrCreateAsciiAtom("()" + TypeReference.findOrCreate(valueType).getName()))
           .asMethodReference();
   try {
     return methRef.resolve().getAnnotationDefault();
   } catch (Throwable t) {
     return NO_VALUE;
   }
 }
  @Nullable
  public static String getMethodParameterAt(@NotNull MethodReference methodReference, int index) {

    ParameterList parameterList = methodReference.getParameterList();
    if (parameterList == null) {
      return null;
    }

    return getMethodParameterAt(parameterList, index);
  }
  private static void attachOnDefaultOptions(
      Project project, HashMap<String, String> defaultValues, String typeClass) {

    PsiElement setDefaultOptions =
        PhpElementsUtil.getPsiElementsBySignatureSingle(
            project, "#M#C\\" + typeClass + ".setDefaultOptions");
    if (setDefaultOptions == null) {
      return;
    }

    Collection<MethodReference> tests =
        PsiTreeUtil.findChildrenOfType(setDefaultOptions, MethodReference.class);
    for (MethodReference methodReference : tests) {
      // instance check
      // methodReference.getSignature().equals("#M#C\\Symfony\\Component\\OptionsResolver\\OptionsResolverInterface.setDefaults")
      if (PhpElementsUtil.isEqualMethodReferenceName(methodReference, "setDefaults")) {
        PsiElement[] parameters = methodReference.getParameters();
        if (parameters.length > 0 && parameters[0] instanceof ArrayCreationExpression) {
          for (String key :
              PhpElementsUtil.getArrayCreationKeys((ArrayCreationExpression) parameters[0])) {
            defaultValues.put(key, typeClass);
          }
        }
      }

      // support: parent::setDefaultOptions($resolver)
      // Symfony\Component\Form\Extension\Core\Type\FormType:setDefaultOptions
      if (PhpElementsUtil.isEqualMethodReferenceName(methodReference, "setDefaultOptions")
          && methodReference.getReferenceType() == PhpModifier.State.PARENT) {
        PsiElement parentMethod =
            PhpElementsUtil.getPsiElementsBySignatureSingle(
                project, methodReference.getSignature());
        if (parentMethod instanceof Method) {
          PhpClass phpClass = ((Method) parentMethod).getContainingClass();
          if (phpClass != null) {
            attachOnDefaultOptions(project, defaultValues, phpClass.getPresentableFQN());
          }
        }
      }
    }
  }
 @Override
 public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef)
     throws IOException {
   switch (methodRef.getName()) {
     case "toJavaScript":
       generateToJavaScript(context, writer);
       break;
     case "fromJavaScript":
       generateFromJavaScript(context, writer);
       break;
   }
 }
  @Nullable
  public static PsiElement getArrayKeyValueInsideSignaturePsi(
      Project project, String signature, String methodName, String keyName) {

    PsiElement psiElement = PhpElementsUtil.getPsiElementsBySignatureSingle(project, signature);
    if (psiElement == null) {
      return null;
    }

    for (MethodReference methodReference :
        PsiTreeUtil.findChildrenOfType(psiElement, MethodReference.class)) {

      if (PhpElementsUtil.isEqualMethodReferenceName(methodReference, methodName)) {
        PsiElement[] parameters = methodReference.getParameters();
        if (parameters.length > 0 && parameters[0] instanceof ArrayCreationExpression) {
          return PhpElementsUtil.getArrayValue((ArrayCreationExpression) parameters[0], keyName);
        }
      }
    }

    return null;
  }
示例#10
0
  @Override
  public GenericParameter findTypeVariable(final String name) {
    for (final GenericParameter genericParameter : getGenericParameters()) {
      if (StringUtilities.equals(genericParameter.getName(), name)) {
        return genericParameter;
      }
    }

    final MethodReference declaringMethod = getDeclaringMethod();

    if (declaringMethod != null) {
      return declaringMethod.findTypeVariable(name);
    }

    final TypeReference declaringType = getDeclaringType();

    if (declaringType != null && !this.isStatic()) {
      return declaringType.findTypeVariable(name);
    }

    return null;
  }
示例#11
0
 /**
  * Read the pair from the input stream and create object
  *
  * @param constantPool the constant pool for the class being read
  * @param input stream to read from
  * @param classLoader the class loader being used to load this annotation
  * @return a newly created annotation member
  */
 static AnnotationMember readAnnotationMember(
     TypeReference type, int[] constantPool, DataInputStream input, ClassLoader classLoader)
     throws IOException, ClassNotFoundException {
   // Read name of pair
   int elemNameIndex = input.readUnsignedShort();
   Atom name = RVMClass.getUtf(constantPool, elemNameIndex);
   MethodReference meth;
   Object value;
   if (type.isResolved()) {
     meth = type.resolve().asClass().findDeclaredMethod(name).getMemberRef().asMethodReference();
     value = RVMAnnotation.readValue(meth.getReturnType(), constantPool, input, classLoader);
   } else {
     value = RVMAnnotation.readValue(null, constantPool, input, classLoader);
     meth =
         MemberReference.findOrCreate(
                 type,
                 name,
                 Atom.findOrCreateAsciiAtom(
                     "()" + TypeReference.findOrCreate(value.getClass()).getName()))
             .asMethodReference();
   }
   return new AnnotationMember(meth, value);
 }
 /**
  * Create a method for reflectively invoking this method
  *
  * @param reflectionClass the class this method will belong to
  * @param constantPool for the class
  * @param memRef the member reference corresponding to this method
  * @return the created method
  */
 RVMMethod createReflectionMethod(
     TypeReference reflectionClass, int[] constantPool, MethodReference memRef) {
   TypeReference[] parameters = getParameterTypes();
   int numParams = parameters.length;
   byte[] bytecodes;
   boolean interfaceCall = false;
   int curBC = 0;
   if (!isStatic()) {
     if (!getDeclaringClass().isInterface()) {
       // virtual call
       bytecodes = new byte[8 * numParams + 8];
     } else {
       // interface call
       bytecodes = new byte[8 * numParams + 10];
       interfaceCall = true;
     }
     bytecodes[curBC] = JBC_aload_1;
     curBC++;
   } else {
     // static call
     bytecodes = new byte[8 * numParams + 7];
   }
   for (int i = 0; i < numParams; i++) {
     if (parameters[i].isVoidType()) {
       bytecodes[curBC] =
           bytecodes[curBC + 1] =
               bytecodes[curBC + 2] =
                   bytecodes[curBC + 3] =
                       bytecodes[curBC + 4] =
                           bytecodes[curBC + 5] =
                               bytecodes[curBC + 6] = bytecodes[curBC + 7] = (byte) JBC_nop;
       continue;
     }
     bytecodes[curBC] = (byte) JBC_aload_2;
     bytecodes[curBC + 1] = (byte) JBC_sipush;
     bytecodes[curBC + 2] = (byte) (i >>> 8);
     bytecodes[curBC + 3] = (byte) i;
     bytecodes[curBC + 4] = (byte) JBC_aaload;
     if (!parameters[i].isPrimitiveType()) {
       bytecodes[curBC + 5] = (byte) JBC_checkcast;
       if (VM.VerifyAssertions) VM._assert(parameters[i].getId() != 0);
       constantPool[i + 1] = ClassFileReader.packCPEntry(CP_CLASS, parameters[i].getId());
       bytecodes[curBC + 6] = (byte) ((i + 1) >>> 8);
       bytecodes[curBC + 7] = (byte) (i + 1);
     } else if (parameters[i].isWordLikeType()) {
       bytecodes[curBC + 5] = bytecodes[curBC + 6] = bytecodes[curBC + 7] = (byte) JBC_nop;
     } else {
       bytecodes[curBC + 5] = (byte) JBC_invokestatic;
       MemberReference unboxMethod;
       if (parameters[i].isBooleanType()) {
         unboxMethod =
             MethodReference.findOrCreate(
                 baseReflectionClass,
                 Atom.findOrCreateUnicodeAtom("unboxAsBoolean"),
                 Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)Z"));
       } else if (parameters[i].isByteType()) {
         unboxMethod =
             MethodReference.findOrCreate(
                 baseReflectionClass,
                 Atom.findOrCreateUnicodeAtom("unboxAsByte"),
                 Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)B"));
       } else if (parameters[i].isShortType()) {
         unboxMethod =
             MethodReference.findOrCreate(
                 baseReflectionClass,
                 Atom.findOrCreateUnicodeAtom("unboxAsShort"),
                 Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)S"));
       } else if (parameters[i].isCharType()) {
         unboxMethod =
             MethodReference.findOrCreate(
                 baseReflectionClass,
                 Atom.findOrCreateUnicodeAtom("unboxAsChar"),
                 Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)C"));
       } else if (parameters[i].isIntType()) {
         unboxMethod =
             MethodReference.findOrCreate(
                 baseReflectionClass,
                 Atom.findOrCreateUnicodeAtom("unboxAsInt"),
                 Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)I"));
       } else if (parameters[i].isLongType()) {
         unboxMethod =
             MethodReference.findOrCreate(
                 baseReflectionClass,
                 Atom.findOrCreateUnicodeAtom("unboxAsLong"),
                 Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)J"));
       } else if (parameters[i].isFloatType()) {
         unboxMethod =
             MethodReference.findOrCreate(
                 baseReflectionClass,
                 Atom.findOrCreateUnicodeAtom("unboxAsFloat"),
                 Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)F"));
       } else {
         if (VM.VerifyAssertions) VM._assert(parameters[i].isDoubleType());
         unboxMethod =
             MethodReference.findOrCreate(
                 baseReflectionClass,
                 Atom.findOrCreateUnicodeAtom("unboxAsDouble"),
                 Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)D"));
       }
       constantPool[i + 1] = ClassFileReader.packCPEntry(CP_MEMBER, unboxMethod.getId());
       bytecodes[curBC + 6] = (byte) ((i + 1) >>> 8);
       bytecodes[curBC + 7] = (byte) (i + 1);
     }
     curBC += 8;
   }
   if (isStatic()) {
     bytecodes[curBC] = (byte) JBC_invokestatic;
   } else if (isObjectInitializer() || isPrivate()) {
     bytecodes[curBC] = (byte) JBC_invokespecial;
   } else if (interfaceCall) {
     bytecodes[curBC] = (byte) JBC_invokeinterface;
   } else {
     bytecodes[curBC] = (byte) JBC_invokevirtual;
   }
   constantPool[numParams + 1] = ClassFileReader.packCPEntry(CP_MEMBER, getId());
   bytecodes[curBC + 1] = (byte) ((numParams + 1) >>> 8);
   bytecodes[curBC + 2] = (byte) (numParams + 1);
   if (interfaceCall) {
     // invokeinterface bytecodes are historically longer than others
     curBC += 2;
   }
   TypeReference returnType = getReturnType();
   if (!returnType.isPrimitiveType() || returnType.isWordLikeType()) {
     bytecodes[curBC + 3] = (byte) JBC_nop;
     bytecodes[curBC + 4] = (byte) JBC_nop;
     bytecodes[curBC + 5] = (byte) JBC_nop;
   } else if (returnType.isVoidType()) {
     bytecodes[curBC + 3] = (byte) JBC_aconst_null;
     bytecodes[curBC + 4] = (byte) JBC_nop;
     bytecodes[curBC + 5] = (byte) JBC_nop;
   } else {
     MemberReference boxMethod;
     if (returnType.isBooleanType()) {
       boxMethod =
           MethodReference.findOrCreate(
               baseReflectionClass,
               Atom.findOrCreateUnicodeAtom("boxAsBoolean"),
               Atom.findOrCreateUnicodeAtom("(Z)Ljava/lang/Object;"));
     } else if (returnType.isByteType()) {
       boxMethod =
           MethodReference.findOrCreate(
               baseReflectionClass,
               Atom.findOrCreateUnicodeAtom("boxAsByte"),
               Atom.findOrCreateUnicodeAtom("(B)Ljava/lang/Object;"));
     } else if (returnType.isShortType()) {
       boxMethod =
           MethodReference.findOrCreate(
               baseReflectionClass,
               Atom.findOrCreateUnicodeAtom("boxAsShort"),
               Atom.findOrCreateUnicodeAtom("(S)Ljava/lang/Object;"));
     } else if (returnType.isCharType()) {
       boxMethod =
           MethodReference.findOrCreate(
               baseReflectionClass,
               Atom.findOrCreateUnicodeAtom("boxAsChar"),
               Atom.findOrCreateUnicodeAtom("(C)Ljava/lang/Object;"));
     } else if (returnType.isIntType()) {
       boxMethod =
           MethodReference.findOrCreate(
               baseReflectionClass,
               Atom.findOrCreateUnicodeAtom("boxAsInt"),
               Atom.findOrCreateUnicodeAtom("(I)Ljava/lang/Object;"));
     } else if (returnType.isLongType()) {
       boxMethod =
           MethodReference.findOrCreate(
               baseReflectionClass,
               Atom.findOrCreateUnicodeAtom("boxAsLong"),
               Atom.findOrCreateUnicodeAtom("(J)Ljava/lang/Object;"));
     } else if (returnType.isFloatType()) {
       boxMethod =
           MethodReference.findOrCreate(
               baseReflectionClass,
               Atom.findOrCreateUnicodeAtom("boxAsFloat"),
               Atom.findOrCreateUnicodeAtom("(F)Ljava/lang/Object;"));
     } else {
       if (VM.VerifyAssertions) VM._assert(returnType.isDoubleType());
       boxMethod =
           MethodReference.findOrCreate(
               baseReflectionClass,
               Atom.findOrCreateUnicodeAtom("boxAsDouble"),
               Atom.findOrCreateUnicodeAtom("(D)Ljava/lang/Object;"));
     }
     constantPool[numParams + 2] = ClassFileReader.packCPEntry(CP_MEMBER, boxMethod.getId());
     bytecodes[curBC + 3] = (byte) JBC_invokestatic;
     bytecodes[curBC + 4] = (byte) ((numParams + 2) >>> 8);
     bytecodes[curBC + 5] = (byte) (numParams + 2);
   }
   bytecodes[curBC + 6] = (byte) JBC_areturn;
   return new NormalMethod(
       reflectionClass,
       memRef,
       (short) (ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC),
       null,
       (short) 3,
       (short) (getParameterWords() + 2),
       bytecodes,
       null,
       null,
       null,
       constantPool,
       null,
       null,
       null,
       null);
 }
示例#13
0
 /** Compute hashCode from meth */
 public int hashCode() {
   return meth.hashCode();
 }
示例#14
0
 /** @return the name of the of the given pair */
 Atom getName() {
   return meth.getName();
 }
示例#15
0
 private List<Instruction> transformInvoke(InvokeInstruction insn) {
   if (insn.getType() != InvocationType.VIRTUAL) {
     return null;
   }
   MethodReference method = insn.getMethod();
   if (method.getClassName().equals(ResourceArray.class.getName())
       || method.getClassName().equals(ResourceMap.class.getName())) {
     if (method.getName().equals("keys")) {
       return transformKeys(insn);
     }
     InvokeInstruction accessInsn = new InvokeInstruction();
     accessInsn.setType(InvocationType.SPECIAL);
     ValueType[] types = new ValueType[method.getDescriptor().parameterCount() + 2];
     types[0] = ValueType.object("java.lang.Object");
     System.arraycopy(
         method.getDescriptor().getSignature(),
         0,
         types,
         1,
         method.getDescriptor().parameterCount() + 1);
     accessInsn.setMethod(
         new MethodReference(ResourceAccessor.class.getName(), method.getName(), types));
     accessInsn.getArguments().add(insn.getInstance());
     accessInsn.getArguments().addAll(insn.getArguments());
     accessInsn.setReceiver(insn.getReceiver());
     return Arrays.asList(accessInsn);
   }
   ClassReader iface = innerSource.get(method.getClassName());
   if (iface == null
       || !innerSource.isSuperType(Resource.class.getName(), iface.getName()).orElse(false)) {
     return null;
   }
   if (method.getName().startsWith("get")) {
     if (method.getName().length() > 3) {
       return transformGetterInvocation(insn, getPropertyName(method.getName().substring(3)));
     }
   } else if (method.getName().startsWith("is")) {
     if (method.getName().length() > 2) {
       return transformGetterInvocation(insn, getPropertyName(method.getName().substring(2)));
     }
   } else if (method.getName().startsWith("set")) {
     if (method.getName().length() > 3) {
       return transformSetterInvocation(insn, getPropertyName(method.getName().substring(3)));
     }
   }
   return null;
 }
示例#16
0
 @Override
 public final String getName() {
   return _baseMethod.getName();
 }
  @NotNull
  public static PsiElement createCompilerPass(
      @NotNull PhpClass bundleClass, @NotNull String className) throws Exception {

    VirtualFile directory =
        bundleClass.getContainingFile().getContainingDirectory().getVirtualFile();
    if (fileExists(directory, className)) {
      throw new Exception("File already exists");
    }

    PhpPsiElement scopeForUseOperator = PhpCodeInsightUtil.findScopeForUseOperator(bundleClass);
    if (scopeForUseOperator == null) {
      throw new Exception("No 'use' scope found");
    }

    VirtualFile compilerDirectory = getAndCreateCompilerDirectory(directory);
    if (compilerDirectory == null) {
      throw new Exception("Directory creation failed");
    }

    Project project = bundleClass.getProject();

    if (bundleClass.findOwnMethodByName("build") == null) {

      insertUseIfNecessary(
          scopeForUseOperator, "\\Symfony\\Component\\DependencyInjection\\ContainerBuilder");

      Method method =
          PhpPsiElementFactory.createMethod(
              project,
              ""
                  + "public function build(ContainerBuilder $container)\n"
                  + "    {\n"
                  + "        parent::build($container);\n"
                  + "    }");

      PhpCodeEditUtil.insertClassMember(bundleClass, method);
    }

    Method buildMethod = bundleClass.findOwnMethodByName("build");
    if (buildMethod == null) {
      throw new Exception("No 'build' method found");
    }

    String relativePath = VfsUtil.getRelativePath(compilerDirectory, directory);
    if (relativePath == null) {
      throw new Exception("path error");
    }

    MethodReference methodReference =
        PhpPsiElementFactory.createMethodReference(
            project, "$container->addCompilerPass(new " + className + "());");

    String ns = bundleClass.getNamespaceName() + relativePath.replace("/", "\\");
    String nsClass = ns + "\\" + className;

    insertUseIfNecessary(scopeForUseOperator, nsClass);

    GroupStatement groupStatement =
        PhpPsiUtil.getChildByCondition(buildMethod, GroupStatement.INSTANCEOF);
    if (groupStatement != null) {
      PsiElement semicolon = methodReference.getNextSibling();
      groupStatement.addRangeBefore(methodReference, semicolon, groupStatement.getLastChild());
    }

    String COMPILER_TEMPLATE = "/resources/fileTemplates/compiler_pass.php";
    String fileTemplateContent = getFileTemplateContent(COMPILER_TEMPLATE);
    if (fileTemplateContent == null) {
      throw new Exception("Template content error");
    }

    String replace =
        fileTemplateContent
            .replace("{{ ns }}", ns.startsWith("\\") ? ns.substring(1) : ns)
            .replace("{{ class }}", className);
    PsiFile fileFromText =
        PsiFileFactory.getInstance(project)
            .createFileFromText(className + ".php", PhpFileType.INSTANCE, replace);
    CodeStyleManager.getInstance(project).reformat(fileFromText);

    return PsiDirectoryFactory.getInstance(project)
        .createDirectory(compilerDirectory)
        .add(fileFromText);
  }
示例#18
0
 public static MethodHandle constructorCaller(MethodReference method) {
   return constructorCaller(method.getClassName(), method.getDescriptor());
 }
示例#19
0
 public static MethodHandle interfaceCaller(MethodReference method) {
   return interfaceCaller(method.getClassName(), method.getDescriptor());
 }
示例#20
0
 public static MethodHandle specialCaller(MethodReference method) {
   return specialCaller(method.getClassName(), method.getDescriptor());
 }
示例#21
0
 @Override
 public MethodDefinition resolve() {
   return _baseMethod.resolve();
 }
  private Map<String, String> findRootDefinition(Collection<MethodReference> methodReferences) {

    Map<String, String> roots = new HashMap<String, String>();

    if (methodReferences.size() == 0) {
      return roots;
    }

    String rootAlias = null;
    String repository = null;

    for (MethodReference methodReference : methodReferences) {
      String methodReferenceName = methodReference.getName();

      // get alias
      // ->createQueryBuilder('test');
      if ("createQueryBuilder".equals(methodReferenceName)) {
        String possibleAlias =
            PhpElementsUtil.getStringValue(
                PsiElementUtils.getMethodParameterPsiElementAt(methodReference, 0));
        if (possibleAlias != null) {
          rootAlias = possibleAlias;
        }
      }

      // find repository class
      // getRepository('Foo')->createQueryBuilder('test');
      if ("getRepository".equals(methodReferenceName)) {
        String possibleRepository =
            PhpElementsUtil.getStringValue(
                PsiElementUtils.getMethodParameterPsiElementAt(methodReference, 0));
        if (possibleRepository != null) {
          repository = possibleRepository;
          PhpClass phpClass = EntityHelper.resolveShortcutName(project, repository);
          if (phpClass != null) {
            repository = phpClass.getPresentableFQN();
          }
        }
      }

      // $qb->from('Foo\Class', 'article')
      if ("from".equals(methodReferenceName)) {
        String table =
            PhpElementsUtil.getStringValue(
                PsiElementUtils.getMethodParameterPsiElementAt(methodReference, 0));
        String alias =
            PhpElementsUtil.getStringValue(
                PsiElementUtils.getMethodParameterPsiElementAt(methodReference, 1));
        if (table != null && alias != null) {
          PhpClass phpClass = EntityHelper.resolveShortcutName(project, table);
          if (phpClass != null) {
            table = phpClass.getPresentableFQN();
          }

          roots.put(table, alias);
        }
      }
    }

    // we have a valid root so add it
    if (rootAlias != null && repository != null) {
      roots.put(repository, rootAlias);
    }

    // we found a alias but not a repository name, so try a scope search if we are inside repository
    // class
    // class implements \Doctrine\Common\Persistence\ObjectRepository, so search for model name of
    // "repositoryClass"
    if (rootAlias != null && repository == null) {
      MethodReference methodReference = methodReferences.iterator().next();
      PhpClass phpClass = PsiTreeUtil.getParentOfType(methodReference, PhpClass.class);
      if (new Symfony2InterfacesUtil()
          .isInstanceOf(phpClass, "\\Doctrine\\Common\\Persistence\\ObjectRepository")) {
        for (DoctrineModel model : EntityHelper.getModelClasses(project)) {
          String className = model.getPhpClass().getPresentableFQN();
          if (className != null) {
            PhpClass resolvedRepoName = EntityHelper.getEntityRepositoryClass(project, className);
            if (PhpElementsUtil.isEqualClassName(resolvedRepoName, phpClass.getPresentableFQN())) {
              roots.put(className, rootAlias);
              return roots;
            }
          }
        }
      }
    }

    // search on PhpTypeProvider
    // $er->createQueryBuilder()
    if (rootAlias != null && repository == null) {
      for (MethodReference methodReference : methodReferences) {
        if ("createQueryBuilder".equals(methodReference.getName())) {
          String signature = methodReference.getSignature();
          int endIndex = signature.lastIndexOf(ObjectRepositoryTypeProvider.TRIM_KEY);
          if (endIndex != -1) {
            String parameter = signature.substring(endIndex + 1);
            int point = parameter.indexOf(".");
            if (point > -1) {
              parameter = parameter.substring(0, point);
              parameter =
                  PhpTypeProviderUtil.getResolvedParameter(
                      PhpIndex.getInstance(project), parameter);
              if (parameter != null) {
                PhpClass phpClass = EntityHelper.resolveShortcutName(project, parameter);
                if (phpClass != null && phpClass.getPresentableFQN() != null) {
                  roots.put(phpClass.getPresentableFQN(), rootAlias);
                  return roots;
                }
              }
            }
          }
        }
      }
    }

    return roots;
  }
 public static boolean isEqualMethodReferenceName(
     MethodReference methodReference, String methodName) {
   String name = methodReference.getName();
   return name != null && name.equals(methodName);
 }
  public QueryBuilderScopeContext collect() {
    QueryBuilderScopeContext qb = new QueryBuilderScopeContext();

    // doctrine needs valid root with an alias, try to find one in method references or scope
    Map<String, String> map = this.findRootDefinition(methodReferences);
    if (map.size() > 0) {
      Map.Entry<String, String> entry = map.entrySet().iterator().next();
      qb.addTable(entry.getKey(), entry.getValue());
    }

    for (MethodReference methodReference : methodReferences) {

      String name = methodReference.getName();
      if (name != null) {
        collectParameter(qb, methodReference, name);
        collectJoins(qb, methodReference, name);
        collectSelects(qb, methodReference, name);
        collectSelectInForm(qb, methodReference, name);
      }
    }

    // first tableMap entry is root, we add several initial data
    if (qb.getTableMap().size() > 0) {
      Map.Entry<String, String> entry = qb.getTableMap().entrySet().iterator().next();
      String className = entry.getKey();
      PhpClass phpClass = PhpElementsUtil.getClassInterface(project, className);

      // add root select fields
      if (phpClass != null) {

        qb.addPropertyAlias(
            entry.getValue(),
            new QueryBuilderPropertyAlias(
                entry.getValue(),
                null,
                new DoctrineModelField(entry.getValue())
                    .addTarget(phpClass)
                    .setTypeName(phpClass.getPresentableFQN())));

        List<QueryBuilderRelation> relationList = new ArrayList<QueryBuilderRelation>();

        // qb.addRelation(entry.getValue(), attachRelationFields(phpClass));
        for (DoctrineModelField field : EntityHelper.getModelFields(phpClass)) {
          qb.addPropertyAlias(
              entry.getValue() + "." + field.getName(),
              new QueryBuilderPropertyAlias(entry.getValue(), field.getName(), field));
          if (field.getRelation() != null && field.getRelationType() != null) {
            relationList.add(new QueryBuilderRelation(field.getName(), field.getRelation()));
          }
        }

        qb.addRelation(entry.getValue(), relationList);
      }

      QueryBuilderRelationClassResolver resolver =
          new QueryBuilderRelationClassResolver(
              project, entry.getValue(), entry.getKey(), qb.getRelationMap(), qb.getJoinMap());
      resolver.collect();
    }

    // we have a querybuilder which complete known elements now
    // se we can builder a property (field) map table from it
    this.buildPropertyMap(qb);

    return qb;
  }