All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.intellij.codeInspection.bytecodeAnalysis.PurityAnalysis Maven / Gradle / Ivy

Go to download

A packaging of the IntelliJ Community Edition java-analysis-impl library. This is release number 1 of trunk branch 142.

The newest version!
/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.codeInspection.bytecodeAnalysis;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.org.objectweb.asm.Opcodes;
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
import org.jetbrains.org.objectweb.asm.tree.InsnList;
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode;
import org.jetbrains.org.objectweb.asm.tree.MethodNode;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
 * Produces equations for inference of @Contract(pure=true) annotations.
 *
 * This simple analysis infers @Contract(pure=true) only if the method doesn't have following instructions.
 * 
    *
  • PUTFIELD
  • *
  • PUTSTATIC
  • *
  • IASTORE
  • *
  • LASTORE
  • *
  • FASTORE
  • *
  • DASTORE
  • *
  • AASTORE
  • *
  • BASTORE
  • *
  • CASTORE
  • *
  • SASTORE
  • *
  • INVOKEDYNAMIC
  • *
  • INVOKEINTERFACE
  • *
* * - Nested calls (via INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL) are processed by transitivity. * @author lambdamix */ public class PurityAnalysis { private static final Result FINAL_TOP = new Final(Value.Top); private static final Result FINAL_PURE = new Final(Value.Pure); static final int UN_ANALYZABLE_FLAG = Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE | Opcodes.ACC_INTERFACE; @NotNull public static Equation analyze(Method method, MethodNode methodNode, boolean stable) { Key key = new Key(method, Direction.Pure, stable); if ((methodNode.access & UN_ANALYZABLE_FLAG) != 0) { return new Equation(key, FINAL_TOP); } InsnList insns = methodNode.instructions; // primary keys of invoked methods Set invokedKeys = new HashSet(); for (int i = 0; i < insns.size(); i++) { AbstractInsnNode insn = insns.get(i); switch (insn.getOpcode()) { case Opcodes.PUTFIELD: case Opcodes.PUTSTATIC: case Opcodes.IASTORE: case Opcodes.LASTORE: case Opcodes.FASTORE: case Opcodes.DASTORE: case Opcodes.AASTORE: case Opcodes.BASTORE: case Opcodes.CASTORE: case Opcodes.SASTORE: case Opcodes.INVOKEDYNAMIC: case Opcodes.INVOKEINTERFACE: return new Equation(key, FINAL_TOP); case Opcodes.INVOKESPECIAL: case Opcodes.INVOKESTATIC: invokedKeys.add(new Key(new Method((MethodInsnNode)insn), Direction.Pure, true)); break; case Opcodes.INVOKEVIRTUAL: invokedKeys.add(new Key(new Method((MethodInsnNode)insn), Direction.Pure, false)); break; default: break; } } if (invokedKeys.isEmpty()) { return new Equation(key, FINAL_PURE); } else { HashSet> sumOfProducts = new HashSet>(); for (Key call : invokedKeys) { sumOfProducts.add(new Product(Value.Top, Collections.singleton(call))); } return new Equation(key, new Pending(sumOfProducts)); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy