diff options
author | Reinier Zwitserloot <reinier@zwitserloot.com> | 2011-05-16 22:32:27 +0200 |
---|---|---|
committer | Reinier Zwitserloot <reinier@zwitserloot.com> | 2011-05-16 22:32:27 +0200 |
commit | 75e81604f390b7d9d14b50a86d9f991de30eb1b3 (patch) | |
tree | 1653754f99d0c7cd2d2ddb9632b128b1fc803850 /src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java | |
parent | 8b2ee73cc46a8629d61abd0dde70ecb0748e2b0e (diff) | |
download | lombok-75e81604f390b7d9d14b50a86d9f991de30eb1b3.tar.gz lombok-75e81604f390b7d9d14b50a86d9f991de30eb1b3.tar.bz2 lombok-75e81604f390b7d9d14b50a86d9f991de30eb1b3.zip |
Split up PatchVal into the ecj and eclipse bits; in ecj you'd just get NoSuchClassErrors.
Diffstat (limited to 'src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java')
-rw-r--r-- | src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java | 115 |
1 files changed, 111 insertions, 4 deletions
diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java index ea53835a..f28ba5a1 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java @@ -1,5 +1,5 @@ /* - * Copyright © 2009-2010 Reinier Zwitserloot and Roel Spilker. + * Copyright © 2009-2011 Reinier Zwitserloot and Roel Spilker. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -43,9 +43,31 @@ import lombok.patcher.scripts.ScriptBuilder; * transformed. */ public class EclipsePatcher extends Agent { + // At some point I'd like the agent to be capable of auto-detecting if its on eclipse or on ecj. This class is a sure sign we're not in ecj but in eclipse. -ReinierZ + @SuppressWarnings("unused") + private static final String ECLIPSE_SIGNATURE_CLASS = "org/eclipse/core/runtime/adaptor/EclipseStarter"; + @Override public void runAgent(String agentArgs, Instrumentation instrumentation, boolean injected) throws Exception { - registerPatchScripts(instrumentation, injected, injected); + String[] args = agentArgs == null ? new String[0] : agentArgs.split(":"); + boolean forceEcj = false; + boolean forceEclipse = false; + for (String arg : args) { + if (arg.trim().equalsIgnoreCase("ECJ")) forceEcj = true; + if (arg.trim().equalsIgnoreCase("ECLIPSE")) forceEclipse = true; + } + if (forceEcj && forceEclipse) { + forceEcj = false; + forceEclipse = false; + } + + boolean ecj; + + if (forceEcj) ecj = true; + else if (forceEclipse) ecj = false; + else ecj = injected; + + registerPatchScripts(instrumentation, injected, ecj); } private static void registerPatchScripts(Instrumentation instrumentation, boolean reloadExistingClasses, boolean ecjOnly) { @@ -274,8 +296,93 @@ public class EclipsePatcher extends Agent { } private static void patchEcjTransformers(ScriptManager sm, boolean ecj) { - PatchDelegate.addPatches(sm, ecj); - PatchVal.addPatches(sm, ecj); + addPatchesForDelegate(sm, ecj); + addPatchesForVal(sm); + if (!ecj) addPatchesForValEclipse(sm); + } + + private static void addPatchesForDelegate(ScriptManager sm, boolean ecj) { + final String CLASSSCOPE_SIG = "org.eclipse.jdt.internal.compiler.lookup.ClassScope"; + + sm.addScript(ScriptBuilder.exitEarly() + .target(new MethodTarget(CLASSSCOPE_SIG, "buildFieldsAndMethods", "void")) + .request(StackRequest.THIS) + .decisionMethod(new Hook(PatchDelegate.class.getName(), "handleDelegateForType", "boolean", CLASSSCOPE_SIG)) + .build()); + } + + private static void addPatchesForValEclipse(ScriptManager sm) { + final String LOCALDECLARATION_SIG = "org.eclipse.jdt.internal.compiler.ast.LocalDeclaration"; + final String PARSER_SIG = "org.eclipse.jdt.internal.compiler.parser.Parser"; + final String VARIABLEDECLARATIONSTATEMENT_SIG = "org.eclipse.jdt.core.dom.VariableDeclarationStatement"; + final String ASTCONVERTER_SIG = "org.eclipse.jdt.core.dom.ASTConverter"; + + sm.addScript(ScriptBuilder.addField() + .fieldName("$initCopy") + .fieldType("Lorg/eclipse/jdt/internal/compiler/ast/ASTNode;") + .setPublic() + .setTransient() + .targetClass("org.eclipse.jdt.internal.compiler.ast.LocalDeclaration") + .build()); + + sm.addScript(ScriptBuilder.addField() + .fieldName("$iterableCopy") + .fieldType("Lorg/eclipse/jdt/internal/compiler/ast/ASTNode;") + .setPublic() + .setTransient() + .targetClass("org.eclipse.jdt.internal.compiler.ast.LocalDeclaration") + .build()); + + sm.addScript(ScriptBuilder.wrapReturnValue() + .target(new MethodTarget(PARSER_SIG, "consumeExitVariableWithInitialization", "void")) + .request(StackRequest.THIS) + .wrapMethod(new Hook("lombok.eclipse.agent.PatchVal", "copyInitializationOfLocalDeclaration", "void", PARSER_SIG)) + .build()); + + sm.addScript(ScriptBuilder.wrapReturnValue() + .target(new MethodTarget(PARSER_SIG, "consumeEnhancedForStatementHeader", "void")) + .request(StackRequest.THIS) + .wrapMethod(new Hook("lombok.eclipse.agent.PatchVal", "copyInitializationOfForEachIterable", "void", PARSER_SIG)) + .build()); + + sm.addScript(ScriptBuilder.wrapReturnValue() + .target(new MethodTarget(ASTCONVERTER_SIG, "setModifiers", "void", VARIABLEDECLARATIONSTATEMENT_SIG, LOCALDECLARATION_SIG)) + .wrapMethod(new Hook("lombok.eclipse.agent.PatchVal", "addFinalAndValAnnotationToVariableDeclarationStatement", + "void", "java.lang.Object", VARIABLEDECLARATIONSTATEMENT_SIG, LOCALDECLARATION_SIG)) + .transplant().request(StackRequest.THIS, StackRequest.PARAM1, StackRequest.PARAM2).build()); + } + + private static void addPatchesForVal(ScriptManager sm) { + final String LOCALDECLARATION_SIG = "org.eclipse.jdt.internal.compiler.ast.LocalDeclaration"; + final String FOREACHSTATEMENT_SIG = "org.eclipse.jdt.internal.compiler.ast.ForeachStatement"; + final String EXPRESSION_SIG = "org.eclipse.jdt.internal.compiler.ast.Expression"; + final String BLOCKSCOPE_SIG = "org.eclipse.jdt.internal.compiler.lookup.BlockScope"; + final String TYPEBINDING_SIG = "org.eclipse.jdt.internal.compiler.lookup.TypeBinding"; + + sm.addScript(ScriptBuilder.exitEarly() + .target(new MethodTarget(LOCALDECLARATION_SIG, "resolve", "void", BLOCKSCOPE_SIG)) + .request(StackRequest.THIS, StackRequest.PARAM1) + .decisionMethod(new Hook("lombok.eclipse.agent.PatchVal", "handleValForLocalDeclaration", "boolean", LOCALDECLARATION_SIG, BLOCKSCOPE_SIG)) + .build()); + + sm.addScript(ScriptBuilder.replaceMethodCall() + .target(new MethodTarget(LOCALDECLARATION_SIG, "resolve", "void", BLOCKSCOPE_SIG)) + .methodToReplace(new Hook(EXPRESSION_SIG, "resolveType", TYPEBINDING_SIG, BLOCKSCOPE_SIG)) + .requestExtra(StackRequest.THIS) + .replacementMethod(new Hook("lombok.eclipse.agent.PatchVal", "skipResolveInitializerIfAlreadyCalled2", TYPEBINDING_SIG, EXPRESSION_SIG, BLOCKSCOPE_SIG, LOCALDECLARATION_SIG)) + .build()); + + sm.addScript(ScriptBuilder.replaceMethodCall() + .target(new MethodTarget(FOREACHSTATEMENT_SIG, "resolve", "void", BLOCKSCOPE_SIG)) + .methodToReplace(new Hook(EXPRESSION_SIG, "resolveType", TYPEBINDING_SIG, BLOCKSCOPE_SIG)) + .replacementMethod(new Hook("lombok.eclipse.agent.PatchVal", "skipResolveInitializerIfAlreadyCalled", TYPEBINDING_SIG, EXPRESSION_SIG, BLOCKSCOPE_SIG)) + .build()); + + sm.addScript(ScriptBuilder.exitEarly() + .target(new MethodTarget(FOREACHSTATEMENT_SIG, "resolve", "void", BLOCKSCOPE_SIG)) + .request(StackRequest.THIS, StackRequest.PARAM1) + .decisionMethod(new Hook("lombok.eclipse.agent.PatchVal", "handleValForForEach", "boolean", FOREACHSTATEMENT_SIG, BLOCKSCOPE_SIG)) + .build()); } private static void patchFixSourceTypeConverter(ScriptManager sm) { |