<commit_before>/*
 * Copyright 2015-2016 <NAME>
 *
 * 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.develorium.metracer;

import java.util.concurrent.atomic.AtomicInteger;
import javassist.*;
import javassist.bytecode.*;

class TracingCodeInjector {
	private String selfPackageName = this.getClass().getPackage().getName() + ".";
	static final String CommonIdentity = "com_develorium_metracer";
	static final String MetracedSuffix = "_" + CommonIdentity;
	static final String RuntimeFieldName = CommonIdentity + "_runtime";
	static final AtomicInteger MetracerNonce = new AtomicInteger();

	public boolean isMethodInstrumentable(CtMethod theMethod) {
		// Do not try to patch ourselves
		if(theMethod.getLongName().startsWith(selfPackageName))
			return false;
		// Do not try to patch interface / abstract / native methods
		int modifiers = theMethod.getModifiers();
		return !Modifier.isInterface(modifiers) && !Modifier.isAbstract(modifiers) && !Modifier.isNative(modifiers);
	}

	public void injectRuntimeReference(CtClass theClass) throws NotFoundException, CannotCompileException {
		CtClass javaLangObject = theClass.getClassPool().get("java.lang.Object");
		CtField runtimeField = new CtField(javaLangObject, RuntimeFieldName, theClass);
		runtimeField.setModifiers(Modifier.STATIC);
		theClass.addField(runtimeField, CtField.Initializer.byExpr("null;"));

		CtConstructor staticConstructor = theClass.makeClassInitializer();

		if(staticConstructor != null) {
			String clFieldName = CommonIdentity + "cl";
			StringBuilder runtimeResolutionCode = new StringBuilder();
			runtimeResolutionCode.append(String.format("java.lang.ClassLoader %1$s = %2$s.class.getClassLoader();", clFieldName, theClass.getName()));
			runtimeResolutionCode.append(String.format("while(%1$s != null) {", clFieldName));
			runtimeResolutionCode.append(String.format(" try {"));
			runtimeResolutionCode.append(String.format("  java.lang.Class c = Class.forName(\"%1$s\", false, %2$s);", Runtime.class.getName(), clFieldName));
			runtimeResolutionCode.append(String.format("  if(c != null) {"));
			runtimeResolutionCode.append(String.format("   java.lang.reflect.Method __getInstanceMethod = c.getMethod(\"getInstance\", null);"));
			runtimeResolutionCode.append(String.format("   %1$s = __getInstanceMethod.invoke(null, null);", RuntimeFieldName));
			runtimeResolutionCode.append(String.format("   java.lang.Class[] __learnClassMethodArgumentTypes = { java.lang.Class.class };"));
			runtimeResolutionCode.append(String.format("   java.lang.reflect.Method __learnClassMethod = c.getMethod(\"learnClass\", __learnClassMethodArgumentTypes);"));
			runtimeResolutionCode.append(String.format("   java.lang.Class[] __learnClassMethodArguments = { %1$s.class };", theClass.getName()));
			runtimeResolutionCode.append(String.format("   __learnClassMethod.invoke(%1$s, __learnClassMethodArguments);", RuntimeFieldName));
			runtimeResolutionCode.append(String.format("   break;"));
			runtimeResolutionCode.append(String.format("  }"));
			runtimeResolutionCode.append(String.format(" } catch(Exception e) {"));
			runtimeResolutionCode.append(String.format(" }"));
			runtimeResolutionCode.append(String.format(" %1$s = %1$s.getParent();", clFieldName));
			runtimeResolutionCode.append(String.format("}"));
			staticConstructor.insertAfter(runtimeResolutionCode.toString());
		}
	}

	public void injectTracingCode(CtClass theClass, CtMethod theMethod) throws NotFoundException, CannotCompileException {
		if(true)
			return;

		String methodNameForPrinting = String.format("%s.%s", theClass.getName(), theMethod.getName());
		String originalMethodName = theMethod.getName();
		// Adding nonce is req-d to avoid unwanted downstream (Base->Inherited) virtual calls from _metraced methods<commit_msg>Use a hack to inspect classes within a ClassLoader<commit_after>/*
 * Copyright 2015-2016 <NAME>
 *
 * 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.develorium.metracer;

import java.util.concurrent.atomic.AtomicInteger;
import javassist.*;
import javassist.bytecode.*;

class TracingCodeInjector {
	private String selfPackageName = this.getClass().getPackage().getName() + ".";
	static final String CommonIdentity = "com_develorium_metracer";
	static final String MetracedSuffix = "_" + CommonIdentity;
	static final String RuntimeFieldName = CommonIdentity + "_runtime";
	static final AtomicInteger MetracerNonce = new AtomicInteger();

	public boolean isMethodInstrumentable(CtMethod theMethod) {
		// Do not try to patch ourselves
		if(theMethod.getLongName().startsWith(selfPackageName))
			return false;
		// Do not try to patch interface / abstract / native methods
		int modifiers = theMethod.getModifiers();
		return !Modifier.isInterface(modifiers) && !Modifier.isAbstract(modifiers) && !Modifier.isNative(modifiers);
	}

	public void injectRuntimeReference(CtClass theClass) throws NotFoundException, CannotCompileException {
		CtClass javaLangObject = theClass.getClassPool().get("java.lang.Object");
		CtField runtimeField = new CtField(javaLangObject, RuntimeFieldName, theClass);
		runtimeField.setModifiers(Modifier.STATIC);
		theClass.addField(runtimeField, CtField.Initializer.byExpr("null;"));

		CtConstructor staticConstructor = theClass.makeClassInitializer();

		if(staticConstructor != null) {
			String clFieldName = CommonIdentity + "cl";
			StringBuilder runtimeResolutionCode = new StringBuilder();
			runtimeResolutionCode.append(String.format("java.lang.ClassLoader %1$s = %2$s.class.getClassLoader();", clFieldName, theClass.getName()));
			runtimeResolutionCode.append(String.format("while(%1$s != null) {", clFieldName));
			//runtimeResolutionCode.append(String.format(" try {"));
			//runtimeResolutionCode.append(String.format("  java.lang.Class c = Class.forName(\"%1$s\", false, %2$s);", Runtime.class.getName(), clFieldName));
			//runtimeResolutionCode.append(String.format("  java.lang.Class c = %1$s.findLoadedClass(\"%2$s\");", clFieldName, Runtime.class.getName()));

			//runtimeResolutionCode.append(String.format("  java.lang.Class c = %1$s.findLoadedClass(\"%2$s\");", clFieldName, Runtime.class.getName()));

			runtimeResolutionCode.append(String.format(" java.lang.reflect.Field f = java.lang.ClassLoader.class.getDeclaredField(\"classes\");"));
			runtimeResolutionCode.append(String.format(" f.setAccessible(true);"));
			runtimeResolutionCode.append(String.format(" java.util.Vector classes = (java.util.Vector)f.get(%1$s);", clFieldName));
			//runtimeResolutionCode.append(String.format(" java.util.Vector classes = null;"));
			//runtimeResolutionCode.append(String.format(" java.util.Vector<java.lang.Class> classes = null;"));
			//runtimeResolutionCode.append(String.format(" f.get(%1$s);", clFieldName));

			runtimeResolutionCode.append(String.format(" for(int i = 0; i < classes.size(); i++) {"));
			runtimeResolutionCode.append(String.format("  java.lang.Class c = (java.lang.Class)classes.get(i);", Runtime.class.getName()));
			runtimeResolutionCode.append(String.format("  if(c != null && c.getName().equals(\"%1$s\")) {", Runtime.class.getName()));
			runtimeResolutionCode.append(String.format("   java.lang.reflect.Method __getInstanceMethod = c.getMethod(\"getInstance\", null);"));
			runtimeResolutionCode.append(String.format("   %1$s = __getInstanceMethod.invoke(null, null);", RuntimeFieldName));
			runtimeResolutionCode.append(String.format("   java.lang.Class[] __learnClassMethodArgumentTypes = { java.lang.Class.class };"));
			runtimeResolutionCode.append(String.format("   java.lang.reflect.Method __learnClassMethod = c.getMethod(\"learnClass\", __learnClassMethodArgumentTypes);"));
			runtimeResolutionCode.append(String.format("   java.lang.Class[] __learnClassMethodArguments = { %1$s.class };", theClass.getName()));
			runtimeResolutionCode.append(String.format("   __learnClassMethod.invoke(%1$s, __learnClassMethodArguments);", RuntimeFieldName));
			runtimeResolutionCode.append(String.format("   break;"));
			runtimeResolutionCode.append(String.format("  }"));
			runtimeResolutionCode.append(String.format(" }"));
			//runtimeResolutionCode.append(String.format(" } catch(Exception e) {"));
			//runtimeResolutionCode.append(String.format(" }"));
			runtimeResolutionCode.append(String.format(" %1$s = %1$s.getParent();", clFieldName));
			runtimeResolutionCode.append(String.format("}"));
			staticConstructor.insertAfter(runtimeResolutionCode.toString());
		}
	}

	public void injectTracingCode(CtClass theClass, CtMethod theMethod) throws NotFoundException, CannotCompileException {
		if(true)
			return;

		String methodNameForPrinting = String.format("%s.%s", theClass.getName(), theMethod.getName());
		String originalMethodName = theMethod.getName();
		// Adding nonce is req-d to avoid unwanted downstream (Base->Inherited) virtual calls from _metraced methods
{'fraction_non_alphanumeric': 0.13452597533858904, 'fraction_numerical': 0.005255710531635335, 'mean_word_length': 5.819434872501723, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5324428', 'n_tokens_mistral': 2977, 'n_tokens_neox': 2777, 'n_words': 604}