public IGoal[] init() {
    ClassVariableDeclarationGoal typedGoal = (ClassVariableDeclarationGoal) goal;
    IType[] types = typedGoal.getTypes();

    if (types == null) {
      TypeContext context = (TypeContext) typedGoal.getContext();
      types = PHPTypeInferenceUtils.getModelElements(context.getInstanceType(), context);
    }
    if (types == null) {
      return null;
    }

    IContext context = typedGoal.getContext();
    IModelAccessCache cache = null;
    if (context instanceof IModelCacheContext) {
      cache = ((IModelCacheContext) context).getCache();
    }

    String variableName = typedGoal.getVariableName();

    final List<IGoal> subGoals = new LinkedList<IGoal>();
    for (final IType type : types) {
      try {
        ITypeHierarchy hierarchy = null;
        if (cache != null) {
          hierarchy = cache.getSuperTypeHierarchy(type, null);
        }
        IField[] fields =
            PHPModelUtils.getTypeHierarchyField(type, hierarchy, variableName, true, null);
        Map<IType, IType> fieldDeclaringTypeSet = new HashMap<IType, IType>();
        for (IField field : fields) {
          IType declaringType = field.getDeclaringType();
          if (declaringType != null) {
            fieldDeclaringTypeSet.put(declaringType, type);
            ISourceModule sourceModule = declaringType.getSourceModule();
            ModuleDeclaration moduleDeclaration =
                SourceParserUtil.getModuleDeclaration(sourceModule);
            TypeDeclaration typeDeclaration =
                PHPModelUtils.getNodeByClass(moduleDeclaration, declaringType);

            if (typeDeclaration != null && field instanceof SourceRefElement) {
              SourceRefElement sourceRefElement = (SourceRefElement) field;
              ISourceRange sourceRange = sourceRefElement.getSourceRange();

              ClassDeclarationSearcher searcher =
                  new ClassDeclarationSearcher(
                      sourceModule,
                      typeDeclaration,
                      sourceRange.getOffset(),
                      sourceRange.getLength(),
                      null,
                      type,
                      declaringType);
              try {
                moduleDeclaration.traverse(searcher);
                if (searcher.getResult() != null) {
                  subGoals.add(new ExpressionTypeGoal(searcher.getContext(), searcher.getResult()));
                }
              } catch (Exception e) {
                if (DLTKCore.DEBUG) {
                  e.printStackTrace();
                }
              }
            }
          }
        }

        if (subGoals.size() == 0) {
          getGoalFromStaticDeclaration(variableName, subGoals, type, null);
        }
        fieldDeclaringTypeSet.remove(type);
        if (subGoals.size() == 0 && !fieldDeclaringTypeSet.isEmpty()) {
          for (Iterator iterator = fieldDeclaringTypeSet.keySet().iterator();
              iterator.hasNext(); ) {
            IType fieldDeclaringType = (IType) iterator.next();
            getGoalFromStaticDeclaration(
                variableName,
                subGoals,
                fieldDeclaringType,
                fieldDeclaringTypeSet.get(fieldDeclaringType));
          }
        }
      } catch (CoreException e) {
        if (DLTKCore.DEBUG) {
          e.printStackTrace();
        }
      }
    }

    resolveMagicClassVariableDeclaration(types, variableName, cache);

    return subGoals.toArray(new IGoal[subGoals.size()]);
  }
Exemplo n.º 2
0
  public IGoal[] init() {
    PHPDocClassVariableGoal typedGoal = (PHPDocClassVariableGoal) goal;
    TypeContext context = (TypeContext) typedGoal.getContext();
    String variableName = typedGoal.getVariableName();
    int offset = typedGoal.getOffset();

    IModelAccessCache cache = context.getCache();
    IType[] types =
        PHPTypeInferenceUtils.getModelElements(context.getInstanceType(), context, offset, cache);
    Map<PHPDocBlock, IField> docs = new HashMap<PHPDocBlock, IField>();
    // remove array index from field name
    if (variableName.endsWith("]")) { // $NON-NLS-1$
      int index = variableName.indexOf("["); // $NON-NLS-1$
      if (index != -1) {
        variableName = variableName.substring(0, index);
      }
    }
    if (types != null) {
      for (IType type : types) {
        try {
          // we look in whole hiearchy
          ITypeHierarchy superHierarchy;
          if (cache != null) {
            superHierarchy = cache.getSuperTypeHierarchy(type, null);
          } else {
            superHierarchy = type.newSupertypeHierarchy(null);
          }
          IType[] superTypes = superHierarchy.getAllTypes();
          for (IType superType : superTypes) {
            IField[] typeField = PHPModelUtils.getTypeField(superType, variableName, true);
            if (typeField.length > 0) {
              PHPDocBlock docBlock = PHPModelUtils.getDocBlock(typeField[0]);
              if (docBlock != null) {
                docs.put(docBlock, typeField[0]);
              }
            }
          }
        } catch (ModelException e) {
          if (DLTKCore.DEBUG) {
            e.printStackTrace();
          }
        }
      }
    }

    for (Entry<PHPDocBlock, IField> entry : docs.entrySet()) {
      PHPDocBlock doc = entry.getKey();
      IField typeField = entry.getValue();
      IType currentNamespace = PHPModelUtils.getCurrentNamespace(typeField);

      IModelElement space =
          currentNamespace != null ? currentNamespace : typeField.getSourceModule();

      for (PHPDocTag tag : doc.getTags(PHPDocTag.VAR)) {
        // do it like for
        // PHPDocumentationContentAccess#handleBlockTags(List tags):
        // variable name can be optional, but if present keep only
        // the good ones
        if (tag.getVariableReference() != null
            && !tag.getVariableReference().getName().equals(variableName)) {
          continue;
        }

        evaluated.addAll(
            Arrays.asList(
                PHPEvaluationUtils.evaluatePHPDocType(
                    tag.getTypeReferences(), space, tag.sourceStart(), null)));
      }
    }

    return IGoal.NO_GOALS;
  }