示例#1
0
  @Override
  public IFigure getTooltip(Object element) {
    if (element instanceof BasicBlock) {
      BasicBlock bb = (BasicBlock) element;
      IR ir = irView.getIR();
      IDocument doc = irView.getDocument();
      IMethod method = ir.getMethod();

      StringBuffer result = new StringBuffer();

      int start = bb.getFirstInstructionIndex();
      int end = bb.getLastInstructionIndex();
      SSAInstruction[] instructions = ir.getInstructions();
      for (int j = start; j <= end; j++) {
        if (instructions[j] != null) {
          int sourceLineNum = method.getLineNumber(j);
          int lineNumber = sourceLineNum - 1; // IDocument indexing is 0-based
          try {
            int lineOffset = doc.getLineOffset(lineNumber);
            int lineLength = doc.getLineLength(lineNumber);
            String sourceCode = doc.get(lineOffset, lineLength).trim();
            result.append(sourceCode);
          } catch (BadLocationException e) {
          }
          result.append("\n");
        }
      }
      return new Label(result.toString());
    }
    return null;
  }
    @Override
    public void visitJavaScriptInvoke(JavaScriptInvoke invk) {
      // check whether this instruction corresponds to a function expression/declaration
      if (isFunctionConstructorInvoke(invk)) {
        int defn = invk.getDef();

        // the name of the function
        String fnName = symtab.getStringValue(invk.getUse(1));
        IClass fnClass =
            cha.lookupClass(TypeReference.findOrCreate(JavaScriptTypes.jsLoader, fnName));
        if (fnClass == null) {
          System.err.println(
              "cannot find " + fnName + " at " + ((AstMethod) method).getSourcePosition());
          return;
        }
        IMethod fn = fnClass.getMethod(AstMethodReference.fnSelector);
        FuncVertex callee = factory.makeFuncVertex(fnClass);

        // look at all uses
        for (Iterator<SSAInstruction> uses = du.getUses(defn); uses.hasNext(); ) {
          SSAInstruction use = uses.next();

          // check whether this is a local call
          if (use instanceof JavaScriptInvoke && ((JavaScriptInvoke) use).getFunction() == defn) {
            JavaScriptInvoke use_invk = (JavaScriptInvoke) use;

            // yes, so add edges from arguments to parameters...
            for (int i = 2; i < use_invk.getNumberOfParameters(); ++i)
              flowgraph.addEdge(
                  factory.makeVarVertex(caller, use_invk.getUse(i)),
                  factory.makeParamVertex(callee, i - 1));

            // ...and from return to result
            flowgraph.addEdge(
                factory.makeRetVertex(callee), factory.makeVarVertex(caller, use.getDef()));

            // note: local calls are never qualified, so there is no flow into the receiver vertex
          } else {
            // no, it's a more complicated use, so add flows from/to unknown
            for (int i = 1; i < fn.getNumberOfParameters(); ++i)
              flowgraph.addEdge(factory.makeUnknownVertex(), factory.makeParamVertex(callee, i));
            flowgraph.addEdge(factory.makeRetVertex(callee), factory.makeUnknownVertex());
          }
        }
      } else {
        // this is a genuine function call; find out where the function came from
        SSAInstruction def = du.getDef(invk.getFunction());

        // if it's not a local call, add flows from/to unknown
        if (!(def instanceof JavaScriptInvoke)
            || !isFunctionConstructorInvoke((JavaScriptInvoke) def)) {
          for (int i = 1; i < invk.getNumberOfParameters(); ++i)
            flowgraph.addEdge(
                factory.makeVarVertex(caller, invk.getUse(i)), factory.makeUnknownVertex());
          flowgraph.addEdge(
              factory.makeUnknownVertex(), factory.makeVarVertex(caller, invk.getDef()));
        }
      }
    }
 /**
  * Get all non-constructor, non-class-initializer methods declared by a class if their name is
  * equal to the specified name.
  *
  * @param cls the class
  * @param name the name
  */
 private Collection<IMethod> getDeclaredNormalMethods(IClass cls, Atom name) {
   Collection<IMethod> result = HashSetFactory.make();
   for (IMethod m : cls.getDeclaredMethods()) {
     if (!m.isInit() && !m.isClinit() && m.getSelector().getName().equals(name)) {
       result.add(m);
     }
   }
   return result;
 }
示例#4
0
  private static void runComputeModule(
      final String binDir, final Config cfg, final String outputDir)
      throws IOException, IllegalArgumentException, CancelException, PDGFormatException,
          WalaException {
    Main.checkOrCreateOutputDir(outputDir);

    System.out.print("Setting up analysis scope... ");

    // Fuegt die normale Java Bibliothek zum Scope hinzu
    AnalysisScope scope = AnalysisScopeReader.makePrimordialScope(null);

    if (cfg.nativesXML != null) {
      com.ibm.wala.ipa.callgraph.impl.Util.setNativeSpec(cfg.nativesXML);
    }

    // if use stubs
    if (cfg.stubs != null) {
      scope.addToScope(ClassLoaderReference.Primordial, new JarFile(cfg.stubs));
    }

    // Nimmt unnoetige Klassen raus
    SetOfClasses exclusions =
        new FileOfClasses(new ByteArrayInputStream(cfg.exclusions.getBytes()));
    scope.setExclusions(exclusions);

    ClassLoaderReference loader = scope.getLoader(AnalysisScope.APPLICATION);
    AnalysisScopeReader.addClassPathToScope(binDir, scope, loader);

    System.out.println("done.");

    ClassHierarchy cha = ClassHierarchy.make(scope);

    System.out.print("Creating MoJo... ");

    MoJo mojo = MoJo.create(cha);

    System.out.println("done.");

    for (IClass cls : cha) {
      for (IMethod im : cls.getDeclaredMethods()) {
        if (im.getDeclaringClass().isInterface() || im.isAbstract()) {
          // skip methods without a body
          continue;
        }

        MethodInfo nfo = cfg.extern.checkForModuleMethod(im);
        if (nfo != null) {
          System.out.println("Found " + nfo + " for " + im);
          final String sig = Dictionary.extractSignature(im);
          final String outputMethodDir =
              outputDir + (outputDir.endsWith(File.separator) ? "" : File.separator) + "m_" + sig;
          Main.checkOrCreateOutputDir(outputMethodDir);
          computeVariants(mojo, im, nfo, outputMethodDir);
        }
      }
    }
  }
示例#5
0
  @Override
  public IMethod getCalleeTarget(CGNode caller, CallSiteReference site, IClass receiver) {
    IMethod target = base.getCalleeTarget(caller, site, receiver);
    if (target != null && target.getReference().equals(loadFileFunRef)) {

      Set<String> names = new HashSet<String>();
      SSAInstruction call =
          caller.getIR()
              .getInstructions()[
              caller.getIR().getCallInstructionIndices(site).intIterator().next()];
      if (call.getNumberOfUses() > 1) {
        LocalPointerKey fileNameV = new LocalPointerKey(caller, call.getUse(1));
        OrdinalSet<InstanceKey> ptrs = builder.getPointerAnalysis().getPointsToSet(fileNameV);
        for (InstanceKey k : ptrs) {
          if (k instanceof ConstantKey) {
            Object v = ((ConstantKey) k).getValue();
            if (v instanceof String) {
              names.add((String) v);
            }
          }
        }

        if (names.size() == 1) {
          String str = names.iterator().next();
          try {
            JavaScriptLoader cl =
                (JavaScriptLoader) builder.getClassHierarchy().getLoader(JavaScriptTypes.jsLoader);
            URL url = new URL(builder.getBaseURL(), str);
            if (!loadedFiles.contains(url)) {
              // try to open the input stream for the URL.  if it fails, we'll get an IOException
              // and fall through to default case
              InputStream inputStream = url.openConnection().getInputStream();
              inputStream.close();
              JSCallGraphUtil.loadAdditionalFile(builder.getClassHierarchy(), cl, url);
              loadedFiles.add(url);
              IClass script =
                  builder
                      .getClassHierarchy()
                      .lookupClass(
                          TypeReference.findOrCreate(cl.getReference(), "L" + url.getFile()));
              return script.getMethod(JavaScriptMethods.fnSelector);
            }
          } catch (MalformedURLException e1) {
            // do nothing, fall through and return 'target'
          } catch (IOException e) {
            // do nothing, fall through and return 'target'
          } catch (RuntimeException e) {
            // do nothing, fall through and return 'target'
          }
        }
      }
    }

    return target;
  }
  @SuppressWarnings("unused")
  public void run() throws UnsoundGraphException {
    Set<CGNode> allCalled = findAllCalledMethods(cg.getEntrypointNodes());

    for (CGNode method : allCalled) {
      IMethod im = method.getMethod();
      if (!im.isNative() && !im.isAbstract() && !im.isSynthetic()) {
        ControlFlowGraph<SSAInstruction, IExplodedBasicBlock> cfg = getPruned(method, null);
      }
    }
  }
 /**
  * Get all non-constructor, non-class-initializer methods declared by a class and all its
  * superclasses if their name is equal to the specified name.
  *
  * @param cls the class
  * @param name the name
  */
 private Collection<IMethod> getAllNormalPublicMethods(IClass cls, Atom name) {
   Collection<IMethod> result = HashSetFactory.make();
   Collection<IMethod> allMethods = null;
   allMethods = cls.getAllMethods();
   for (IMethod m : allMethods) {
     if (!m.isInit() && !m.isClinit() && m.isPublic() && m.getSelector().getName().equals(name)) {
       result.add(m);
     }
   }
   return result;
 }
示例#8
0
 /**
  * @param method
  * @return the receiver class for this method.
  */
 private IClass getReceiverClass(IMethod method) {
   TypeReference formalType = method.getParameterType(0);
   IClass C = cha.lookupClass(formalType);
   if (method.isStatic()) {
     Assertions.UNREACHABLE("asked for receiver of static method " + method);
   }
   if (C == null) {
     Assertions.UNREACHABLE("no class found for " + formalType + " recv of " + method);
   }
   return C;
 }
 public int getMethodEndLineNumber(String methodSig) {
   try {
     for (IMethod method : mInfoMap.keySet()) {
       if (method.getSignature().equals(methodSig)) {
         return mInfoMap.get(method).getEndLineNumber();
       }
     }
     return 0;
   } catch (InvalidClassFileException icfe) {
     return 0;
   }
 }
 public Set<String> getSetOfLinesRelatedToAddedMethods() {
   Set<String> lineNumbersOfAddedMethods = new HashSet<String>();
   for (IMethod method : getAddedMethods()) {
     int getLineNumberOfFirstLineOfMethod = 0;
     try {
       getLineNumberOfFirstLineOfMethod =
           method.getLineNumber(1); // getMethodStartLineNumber(method);
     } catch (Exception e) {
     }
     lineNumbersOfAddedMethods.add(
         getClassName(method.getDeclaringClass()) + "," + getLineNumberOfFirstLineOfMethod);
   }
   return lineNumbersOfAddedMethods;
 }
示例#11
0
 /*
  * @see com.ibm.wala.ipa.callgraph.ContextSelector#getCalleeTarget(com.ibm.wala.ipa.callgraph.CGNode,
  *      com.ibm.wala.classLoader.CallSiteReference, com.ibm.wala.classLoader.IMethod,
  *      com.ibm.wala.ipa.callgraph.propagation.InstanceKey)
  */
 public Context getCalleeTarget(
     CGNode caller, CallSiteReference site, IMethod callee, InstanceKey[] receiver) {
   if (callee.getReference().equals(GET_CLASS)) {
     return new JavaTypeContext(new PointType(receiver[0].getConcreteType()));
   }
   return null;
 }
示例#12
0
  @SuppressWarnings("unchecked")
  public void setIR(IR ir) {
    this.lineToPosition = HashMapFactory.make();
    this.pcToLine = HashMapFactory.make();
    this.lineToPc = HashMapFactory.make();

    int firstLineWithPosition = NA;

    try {
      methodName.setText("IR: " + ir.getMethod());
      irLineList.clear();
      BufferedReader br = new BufferedReader(new StringReader(ir.toString()));
      int lineNum = 0;
      int position = NA;
      String line;
      while ((line = br.readLine()) != null) {
        irLineList.addElement(line);
        int pc = parseIrLine(line);
        if (pc != NA) {
          IMethod m = ir.getMethod();
          int newPosition = m.getLineNumber(pc);
          if (newPosition != -1) {
            position = newPosition;
          }
          lineToPc.put(lineNum, pc);
          pcToLine.put(pc, lineNum);

          if (position != NA) {
            lineToPosition.put(lineNum, position);
            if (firstLineWithPosition == NA) {
              firstLineWithPosition = lineNum;
            }
          }
        }
        lineNum++;
      }
    } catch (IOException e) {
      // ???
      assert false;
    }

    // focusing on the first line with position
    if (firstLineWithPosition != NA) {
      irLines.setSelectedIndex(firstLineWithPosition);
      irLines.ensureIndexIsVisible(firstLineWithPosition);
    }
  }
 /**
  * @param m a method reference
  * @return a SyntheticMethod corresponding to m; or null if none is available.
  */
 protected SyntheticMethod findOrCreateSyntheticMethod(IMethod m, boolean isStatic) {
   MethodReference ref = m.getReference();
   if (syntheticMethods.containsKey(ref)) {
     return syntheticMethods.get(ref);
   } else {
     MethodSummary summ = null;
     if (canIgnore(ref)) {
       summ = generateNoOp(ref, isStatic);
     } else {
       summ = findSummary(ref);
     }
     if (summ != null) {
       SummarizedMethod n = new SummarizedMethod(ref, summ, m.getDeclaringClass());
       syntheticMethods.put(ref, n);
       return n;
     } else {
       syntheticMethods.put(ref, null);
       return null;
     }
   }
 }
示例#14
0
  public static Iterable<Entrypoint> makePrimordialPublicEntrypoints(
      AnalysisScope scope, ClassHierarchy cha, String pkg) {
    final HashSet<Entrypoint> result = HashSetFactory.make();
    for (IClass clazz : cha) {

      if (clazz.getName().toString().indexOf(pkg) != -1
          && !clazz.isInterface()
          && !clazz.isAbstract()) {
        for (IMethod method : clazz.getDeclaredMethods()) {
          if (method.isPublic() && !method.isAbstract()) {
            System.out.println("Entry:" + method.getReference());
            result.add(new DefaultEntrypoint(method, cha));
          }
        }
      }
    }
    return new Iterable<Entrypoint>() {
      @Override
      public Iterator<Entrypoint> iterator() {
        return result.iterator();
      }
    };
  }
示例#15
0
 /**
  * @see
  *     com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter#getIR(com.ibm.wala.ipa.callgraph.CGNode)
  */
 @Override
 public IR getIR(CGNode node) {
   if (node == null) {
     throw new IllegalArgumentException("node is null");
   }
   assert understands(node);
   if (DEBUG) {
     System.err.println("generating IR for " + node);
   }
   IMethod method = node.getMethod();
   GetMethodContext context = (GetMethodContext) node.getContext();
   Map<Integer, ConstantValue> constants = HashMapFactory.make();
   if (method.getReference().equals(GET_METHOD)) {
     Atom name = Atom.findOrCreateAsciiAtom(context.getName());
     SSAInstruction instrs[] = makeGetMethodStatements(context, constants, name);
     return new SyntheticIR(
         method,
         context,
         new InducedCFG(instrs, method, context),
         instrs,
         SSAOptions.defaultOptions(),
         constants);
   }
   if (method.getReference().equals(GET_DECLARED_METHOD)) {
     Atom name = Atom.findOrCreateAsciiAtom(context.getName());
     SSAInstruction instrs[] = makeGetDeclaredMethodStatements(context, constants, name);
     return new SyntheticIR(
         method,
         context,
         new InducedCFG(instrs, method, context),
         instrs,
         SSAOptions.defaultOptions(),
         constants);
   }
   Assertions.UNREACHABLE("Unexpected method " + node);
   return null;
 }
示例#16
0
  private static void computeAliasVariant(
      final MoJo mojo,
      final MayAliasGraph alias,
      final IMethod method,
      final boolean ignoreExceptions,
      final String outDir)
      throws IllegalArgumentException, CancelException, PDGFormatException, WalaException,
          FileNotFoundException {
    final Logger debug = Log.getLogger(Log.L_MOJO_DEBUG);
    final Logger info = Log.getLogger(Log.L_MOJO_INFO);

    info.out("Preparing points-to config and call graph...");
    final PointsTo pts = MoJo.computePointsTo(alias);
    if (debug.isEnabled()) {
      AliasGraphIO.dumpToDot(alias, outDir + ".alias.dot");
    }
    AliasGraphIO.writeOut(alias, new FileOutputStream(outDir + ".alias"));

    final AnalysisOptions optPts = mojo.createAnalysisOptionsWithPTS(pts, method);
    final CallGraphResult cg = mojo.computeContextSensitiveCallGraph(optPts);
    if (debug.isEnabled()) {
      final PrintStream ssaOut = new PrintStream(outDir + ".ssa.txt");
      Util.dumpSSA(cg.cg.getFakeRootNode().getIR(), ssaOut);
      Util.dumpPhiSSA(cg.cg.getFakeRootNode().getIR(), ssaOut);
      ssaOut.flush();
      ssaOut.close();

      Util.dumpHeapGraphToFile(
          outDir + ".heap.dot", cg.pts.getHeapGraph(), cg.cg.getFakeRootNode().getMethod());
    }
    info.out("done, sdg... ");
    // run analysis on callgraph with minimal alias configuration
    // ...
    final edu.kit.joana.ifc.sdg.graph.SDG sdg = createSDG(cg, optPts, method, ignoreExceptions);
    SDGSerializer.toPDGFormat(sdg, new BufferedOutputStream(new FileOutputStream(outDir + ".pdg")));
    info.out("(" + sdg.edgeSet().size() + " edges)");

    if (debug.isEnabled()) {
      final int summary =
          outputSummaryEdges(sdg, method.getReference().getSignature(), outDir + ".sum.dot");
      debug.out(" (" + summary + " sum)");
    }

    info.outln(" done.");
  }
示例#17
0
 public static boolean isRemoteProcedure(IMethod method) {
   return isCapsuleInterface(method.getDeclaringClass());
 }
示例#18
0
  /** Taken from com.ibm.wala.viz.PDFViewUtil */
  @Override
  public String getText(Object element) {
    if (element instanceof BasicBlock) {
      BasicBlock bb = (BasicBlock) element;
      IR ir = irView.getIR();

      StringBuilder result = new StringBuilder();

      int start = bb.getFirstInstructionIndex();
      int end = bb.getLastInstructionIndex();

      result.append("BB").append(bb.getNumber());

      if (bb.isEntryBlock()) {
        result.append(" (en)\n");
      } else if (bb.isExitBlock()) {
        result.append(" (ex)\n");
      }
      if (bb instanceof ExceptionHandlerBasicBlock) {
        result.append("<Handler>");
      }
      result.append("\n");

      for (Iterator<SSAPhiInstruction> it = bb.iteratePhis(); it.hasNext(); ) {
        SSAPhiInstruction phi = it.next();
        if (phi != null) {
          result.append(phi.toString(ir.getSymbolTable())).append("\n");
        }
      }
      if (bb instanceof ExceptionHandlerBasicBlock) {
        ExceptionHandlerBasicBlock ebb = (ExceptionHandlerBasicBlock) bb;
        SSAGetCaughtExceptionInstruction s = ebb.getCatchInstruction();
        if (s != null) {
          result.append(s.toString(ir.getSymbolTable())).append("\n");
        } else {
          result.append(" No catch instruction. Unreachable?\n");
        }
      }

      SSAInstruction[] instructions = ir.getInstructions();
      IMethod method = ir.getMethod();
      for (int j = start; j <= end; j++) {
        if (instructions[j] != null) {
          String x;
          int sourceLineNum = method.getLineNumber(j);
          x =
              String.format(
                  j + " [L%03d] " + instructions[j].toString(ir.getSymbolTable()), sourceLineNum);
          String padded = String.format("%1$-35s", x);
          result.append(padded);
          result.append("\n");
          result.append(SSAValuesToLocalVariables(instructions[j], j, ir));
          result.append("\n");
        }
      }
      for (Iterator<SSAPiInstruction> it = bb.iteratePis(); it.hasNext(); ) {
        SSAPiInstruction pi = it.next();
        if (pi != null) {
          result.append("           " + pi.toString(ir.getSymbolTable())).append("\n");
        }
      }
      return result.toString();
    }
    if (element instanceof EntityConnectionData) {
      return "\n";
    }
    return "";
  }
示例#19
0
 /** @param method An arbitrary method on a template class annotated with `@Capsule`. */
 public static boolean isSpecialCapsuleDecl(IMethod method) {
   assert isCapsuleTemplate(method.getDeclaringClass());
   return isNamed(method, "init") || isNamed(method, "design") || isNamed(method, "run");
 }
示例#20
0
 /** @param method An arbitrary method declared on a template class annotated with `@Capsule`. */
 public static boolean isProcedure(IMethod method) {
   assert isCapsuleTemplate(method.getDeclaringClass());
   return method.isPublic() == true // Only a capsule's public methods are procedures.
       && isSpecialCapsuleDecl(method) == false; // Don't count special decls as procedures.
 }
 public LocalCallSSAVisitor(IMethod method, SymbolTable symtab, DefUse du, FlowGraph flowgraph) {
   super(method, symtab, du);
   this.flowgraph = flowgraph;
   this.factory = flowgraph.getVertexFactory();
   this.caller = this.factory.makeFuncVertex(method.getDeclaringClass());
 }
 protected boolean filterFunction(IMethod function) {
   return function.getDescriptor().equals(AstMethodReference.fnDesc);
 }
示例#23
0
  private static SDGNode convertNode(SDGBuilder sdg, PDGNode node) {
    Operation op = null;
    Kind kind = null;
    int[] allocNodes = null;

    switch (node.getKind()) {
      case ACTUAL_IN:
        op = Operation.ACTUAL_IN;
        kind = Kind.ACTUAL_IN;
        break;
      case ACTUAL_OUT:
        op = Operation.ACTUAL_OUT;
        kind = Kind.ACTUAL_OUT;
        break;
      case CALL:
        op = Operation.CALL;
        kind = Kind.CALL;
        if (sdg.cfg.computeInterference) {
          TIntSet allocNodesAsSet = sdg.getAllocationNodes(node);
          if (allocNodesAsSet != null) {
            allocNodes = allocNodesAsSet.toArray();
          }
        }
        break;
      case ENTRY:
        op = Operation.ENTRY;
        kind = Kind.ENTRY;
        break;
      case EXIT:
        op = Operation.EXIT;
        kind = Kind.EXIT;
        break;
      case EXPRESSION:
        op = Operation.ASSIGN;
        kind = Kind.EXPRESSION;
        break;
      case FOLDED:
        op = Operation.COMPOUND;
        kind = Kind.FOLDED;
        break;
      case FORMAL_IN:
        op = Operation.FORMAL_IN;
        kind = Kind.FORMAL_IN;
        break;
      case FORMAL_OUT:
        op = Operation.FORMAL_OUT;
        kind = Kind.FORMAL_OUT;
        break;
      case HREAD:
        op = Operation.REFERENCE;
        kind = Kind.EXPRESSION;
        break;
      case HWRITE:
        op = Operation.MODIFY;
        kind = Kind.EXPRESSION;
        break;
      case JOIN:
        op = Operation.COMPOUND;
        kind = Kind.JOIN;
        break;
      case NEW:
        op = Operation.DECLARATION;
        kind = Kind.NORMAL;
        break;
      case NORMAL:
        op = Operation.COMPOUND;
        kind = Kind.NORMAL;
        break;
      case PHI:
        op = Operation.ASSIGN;
        kind = Kind.EXPRESSION;
        break;
      case PREDICATE:
        op = Operation.IF;
        kind = Kind.PREDICATE;
        break;
      case SYNCHRONIZATION:
        op = Operation.MONITOR;
        kind = Kind.SYNCHRONIZATION;
        break;
      default:
        throw new IllegalStateException("Unknown node kind: " + node.getKind().name());
    }
    SourceLocation sloc = node.getSourceLocation();

    SDGNode sn =
        new SecurityNode(
            node.getId(),
            op,
            node.getLabel(),
            node.getPdgId(),
            node.getType(),
            sloc.getSourceFile(),
            sloc.getStartRow(),
            sloc.getStartColumn(),
            sloc.getEndRow(),
            sloc.getEndColumn(),
            node.getBytecodeName(),
            node.getBytecodeIndex());

    if (node.getKind() == PDGNode.Kind.ENTRY) {
      PDG pdg = sdg.getPDGforId(node.getPdgId());
      IMethod im = pdg.getMethod();

      if (im != null) {
        IClass cls = im.getDeclaringClass();

        if (cls != null) {
          String clsLoader = cls.getClassLoader().toString();
          sn.setClassLoader(clsLoader);
        }
      }
    }

    if (allocNodes != null) {
      sn.setAllocationSites(allocNodes);
    }

    if (node.getAliasDataSources() != null) {
      sn.setAliasDataSources(node.getAliasDataSources());
    }

    assert sn.getKind() == kind;

    return sn;
  }