You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2017/12/20 04:29:53 UTC
[45/47] groovy git commit: Move source files to proper packages
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/StatementReplacer.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/StatementReplacer.groovy b/src/main/groovy/StatementReplacer.groovy
deleted file mode 100644
index 3a9dab3..0000000
--- a/src/main/groovy/StatementReplacer.groovy
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.codehaus.groovy.transform.tailrec
-
-import groovy.transform.CompileStatic
-import org.codehaus.groovy.ast.ASTNode
-import org.codehaus.groovy.ast.CodeVisitorSupport
-import org.codehaus.groovy.ast.expr.ClosureExpression
-import org.codehaus.groovy.ast.stmt.BlockStatement
-import org.codehaus.groovy.ast.stmt.DoWhileStatement
-import org.codehaus.groovy.ast.stmt.ForStatement
-import org.codehaus.groovy.ast.stmt.IfStatement
-import org.codehaus.groovy.ast.stmt.Statement
-import org.codehaus.groovy.ast.stmt.WhileStatement
-
-/**
- * Tool for replacing Statement objects in an AST by other Statement instances.
- *
- * Within @TailRecursive it is used to swap ReturnStatements with looping back to RECUR label
- *
- * @author Johannes Link
- */
-@CompileStatic
-class StatementReplacer extends CodeVisitorSupport {
-
- Closure<Boolean> when = { Statement node -> false }
- Closure<Statement> replaceWith = { Statement statement -> statement }
- int closureLevel = 0
-
- void replaceIn(ASTNode root) {
- root.visit(this)
- }
-
- public void visitClosureExpression(ClosureExpression expression) {
- closureLevel++
- try {
- super.visitClosureExpression(expression)
- } finally {
- closureLevel--
- }
- }
-
- public void visitBlockStatement(BlockStatement block) {
- List<Statement> copyOfStatements = new ArrayList<Statement>(block.statements)
- copyOfStatements.eachWithIndex { Statement statement, int index ->
- replaceIfNecessary(statement) { Statement node -> block.statements[index] = node }
- }
- super.visitBlockStatement(block);
- }
-
- public void visitIfElse(IfStatement ifElse) {
- replaceIfNecessary(ifElse.ifBlock) { Statement s -> ifElse.ifBlock = s }
- replaceIfNecessary(ifElse.elseBlock) { Statement s -> ifElse.elseBlock = s }
- super.visitIfElse(ifElse);
- }
-
- public void visitForLoop(ForStatement forLoop) {
- replaceIfNecessary(forLoop.loopBlock) { Statement s -> forLoop.loopBlock = s }
- super.visitForLoop(forLoop);
- }
-
- public void visitWhileLoop(WhileStatement loop) {
- replaceIfNecessary(loop.loopBlock) { Statement s -> loop.loopBlock = s }
- super.visitWhileLoop(loop);
- }
-
- public void visitDoWhileLoop(DoWhileStatement loop) {
- replaceIfNecessary(loop.loopBlock) { Statement s -> loop.loopBlock = s }
- super.visitDoWhileLoop(loop);
- }
-
-
- private void replaceIfNecessary(Statement nodeToCheck, Closure replacementCode) {
- if (conditionFulfilled(nodeToCheck)) {
- ASTNode replacement = replaceWith(nodeToCheck)
- replacement.setSourcePosition(nodeToCheck);
- replacement.copyNodeMetaData(nodeToCheck);
- replacementCode(replacement)
- }
- }
-
- private boolean conditionFulfilled(ASTNode nodeToCheck) {
- if (when.maximumNumberOfParameters < 2)
- return when(nodeToCheck)
- else
- return when(nodeToCheck, isInClosure())
- }
-
- private boolean isInClosure() {
- closureLevel > 0
- }
-
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/StringUtil.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/StringUtil.groovy b/src/main/groovy/StringUtil.groovy
deleted file mode 100644
index ed83e53..0000000
--- a/src/main/groovy/StringUtil.groovy
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.codehaus.groovy.util
-
-import groovy.transform.CompileStatic
-
-/**
- * String utility functions.
- */
-@CompileStatic
-class StringUtil {
- /**
- * Provides Groovy with functionality similar to the unix tr command
- * which translates a string replacing characters from a source set
- * with characters from a replacement set.
- *
- * @since 1.7.3
- */
- static String tr(String text, String source, String replacement) {
- if (!text || !source) { return text }
- source = expandHyphen(source)
- replacement = expandHyphen(replacement)
-
- // padding replacement with a last character, if necessary
- replacement = replacement.padRight(source.size(), replacement[replacement.size() - 1])
-
- return text.collect { String original ->
- if (source.contains(original)) {
- replacement[source.lastIndexOf(original)]
- } else {
- original
- }
- }.join('')
- }
-
- // no expansion for hyphen at start or end of Strings
- private static String expandHyphen(String text) {
- if (!text.contains('-')) { return text }
- return text.replaceAll(/(.)-(.)/, { all, begin, end -> (begin..end).join('') })
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/TailRecursiveASTTransformation.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/TailRecursiveASTTransformation.groovy b/src/main/groovy/TailRecursiveASTTransformation.groovy
deleted file mode 100644
index 0605f18..0000000
--- a/src/main/groovy/TailRecursiveASTTransformation.groovy
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.codehaus.groovy.transform.tailrec
-
-import groovy.transform.CompileStatic
-import groovy.transform.Memoized
-import groovy.transform.TailRecursive
-import org.codehaus.groovy.ast.ASTNode
-import org.codehaus.groovy.ast.AnnotationNode
-import org.codehaus.groovy.ast.ClassHelper
-import org.codehaus.groovy.ast.ClassNode
-import org.codehaus.groovy.ast.MethodNode
-import org.codehaus.groovy.ast.Parameter
-import org.codehaus.groovy.ast.expr.Expression
-import org.codehaus.groovy.ast.expr.MethodCallExpression
-import org.codehaus.groovy.ast.expr.StaticMethodCallExpression
-import org.codehaus.groovy.ast.expr.TernaryExpression
-import org.codehaus.groovy.ast.expr.VariableExpression
-import org.codehaus.groovy.ast.stmt.BlockStatement
-import org.codehaus.groovy.ast.stmt.ReturnStatement
-import org.codehaus.groovy.ast.stmt.Statement
-import org.codehaus.groovy.classgen.ReturnAdder
-import org.codehaus.groovy.classgen.VariableScopeVisitor
-import org.codehaus.groovy.control.CompilePhase
-import org.codehaus.groovy.control.SourceUnit
-import org.codehaus.groovy.transform.AbstractASTTransformation
-import org.codehaus.groovy.transform.GroovyASTTransformation
-
-/**
- * Handles generation of code for the @TailRecursive annotation.
- *
- * It's doing its work in the earliest possible compile phase
- *
- * @author Johannes Link
- */
-@CompileStatic
-@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
-class TailRecursiveASTTransformation extends AbstractASTTransformation {
-
- private static final Class MY_CLASS = TailRecursive.class;
- private static final ClassNode MY_TYPE = new ClassNode(MY_CLASS);
- static final String MY_TYPE_NAME = "@" + MY_TYPE.getNameWithoutPackage()
- private HasRecursiveCalls hasRecursiveCalls = new HasRecursiveCalls()
- private TernaryToIfStatementConverter ternaryToIfStatement = new TernaryToIfStatementConverter()
-
-
- @Override
- public void visit(ASTNode[] nodes, SourceUnit source) {
- init(nodes, source);
-
- MethodNode method = nodes[1] as MethodNode
-
- if (method.isAbstract()) {
- addError("Annotation " + MY_TYPE_NAME + " cannot be used for abstract methods.", method);
- return;
- }
-
- if (hasAnnotation(method, ClassHelper.make(Memoized))) {
- ClassNode memoizedClassNode = ClassHelper.make(Memoized)
- for (AnnotationNode annotationNode in method.annotations) {
- if (annotationNode.classNode == MY_TYPE)
- break
- if (annotationNode.classNode == memoizedClassNode) {
- addError("Annotation " + MY_TYPE_NAME + " must be placed before annotation @Memoized.", annotationNode)
- return
- }
- }
- }
-
- if (!hasRecursiveMethodCalls(method)) {
- AnnotationNode annotationNode = method.getAnnotations(ClassHelper.make(TailRecursive))[0]
- addError("No recursive calls detected. You must remove annotation " + MY_TYPE_NAME + ".", annotationNode)
- return;
- }
-
- transformToIteration(method, source)
- ensureAllRecursiveCallsHaveBeenTransformed(method)
- }
-
- private boolean hasAnnotation(MethodNode methodNode, ClassNode annotation) {
- List annots = methodNode.getAnnotations(annotation);
- return (annots != null && annots.size() > 0);
- }
-
-
- private void transformToIteration(MethodNode method, SourceUnit source) {
- if (method.isVoidMethod()) {
- transformVoidMethodToIteration(method, source)
- } else {
- transformNonVoidMethodToIteration(method, source)
- }
- }
-
- private void transformVoidMethodToIteration(MethodNode method, SourceUnit source) {
- addError("Void methods are not supported by @TailRecursive yet.", method)
- }
-
- private void transformNonVoidMethodToIteration(MethodNode method, SourceUnit source) {
- addMissingDefaultReturnStatement(method)
- replaceReturnsWithTernariesToIfStatements(method)
- wrapMethodBodyWithWhileLoop(method)
-
- Map<String, Map> nameAndTypeMapping = name2VariableMappingFor(method)
- replaceAllAccessToParams(method, nameAndTypeMapping)
- addLocalVariablesForAllParameters(method, nameAndTypeMapping) //must happen after replacing access to params
-
- Map<Integer, Map> positionMapping = position2VariableMappingFor(method)
- replaceAllRecursiveReturnsWithIteration(method, positionMapping)
- repairVariableScopes(source, method)
- }
-
- private void repairVariableScopes(SourceUnit source, MethodNode method) {
- new VariableScopeVisitor(source).visitClass(method.declaringClass)
- }
-
- private void replaceReturnsWithTernariesToIfStatements(MethodNode method) {
- Closure<Boolean> whenReturnWithTernary = { ASTNode node ->
- if (!(node instanceof ReturnStatement)) {
- return false
- }
- return (((ReturnStatement) node).expression instanceof TernaryExpression)
- }
- Closure<Statement> replaceWithIfStatement = { ReturnStatement statement ->
- ternaryToIfStatement.convert(statement)
- }
- StatementReplacer replacer = new StatementReplacer(when: whenReturnWithTernary, replaceWith: replaceWithIfStatement)
- replacer.replaceIn(method.code)
-
- }
-
- private void addLocalVariablesForAllParameters(MethodNode method, Map<String, Map> nameAndTypeMapping) {
- BlockStatement code = method.code as BlockStatement
- nameAndTypeMapping.each { String paramName, Map localNameAndType ->
- code.statements.add(0, AstHelper.createVariableDefinition(
- (String) localNameAndType['name'],
- (ClassNode) localNameAndType['type'],
- new VariableExpression(paramName, (ClassNode) localNameAndType['type'])
- ))
- }
- }
-
- private void replaceAllAccessToParams(MethodNode method, Map<String, Map> nameAndTypeMapping) {
- new VariableAccessReplacer(nameAndTypeMapping: nameAndTypeMapping).replaceIn(method.code)
- }
-
- // Public b/c there are tests for this method
- Map<String, Map> name2VariableMappingFor(MethodNode method) {
- Map<String, Map> nameAndTypeMapping = [:]
- method.parameters.each { Parameter param ->
- String paramName = param.name
- ClassNode paramType = param.type as ClassNode
- String iterationVariableName = iterationVariableName(paramName)
- nameAndTypeMapping[paramName] = [name: iterationVariableName, type: paramType]
- }
- return nameAndTypeMapping
- }
-
- // Public b/c there are tests for this method
- Map<Integer, Map> position2VariableMappingFor(MethodNode method) {
- Map<Integer, Map> positionMapping = [:]
- method.parameters.eachWithIndex { Parameter param, int index ->
- String paramName = param.name
- ClassNode paramType = param.type as ClassNode
- String iterationVariableName = this.iterationVariableName(paramName)
- positionMapping[index] = [name: iterationVariableName, type: paramType]
- }
- return positionMapping
- }
-
- private String iterationVariableName(String paramName) {
- '_' + paramName + '_'
- }
-
- private void replaceAllRecursiveReturnsWithIteration(MethodNode method, Map positionMapping) {
- replaceRecursiveReturnsOutsideClosures(method, positionMapping)
- replaceRecursiveReturnsInsideClosures(method, positionMapping)
- }
-
- private void replaceRecursiveReturnsOutsideClosures(MethodNode method, Map<Integer, Map> positionMapping) {
- Closure<Boolean> whenRecursiveReturn = { Statement statement, boolean inClosure ->
- if (inClosure)
- return false
- if (!(statement instanceof ReturnStatement)) {
- return false
- }
- Expression inner = ((ReturnStatement) statement).expression
- if (!(inner instanceof MethodCallExpression) && !(inner instanceof StaticMethodCallExpression)) {
- return false
- }
- return isRecursiveIn(inner, method)
- }
- Closure<Statement> replaceWithContinueBlock = { ReturnStatement statement ->
- new ReturnStatementToIterationConverter().convert(statement, positionMapping)
- }
- def replacer = new StatementReplacer(when: whenRecursiveReturn, replaceWith: replaceWithContinueBlock)
- replacer.replaceIn(method.code)
- }
-
- private void replaceRecursiveReturnsInsideClosures(MethodNode method, Map<Integer, Map> positionMapping) {
- Closure<Boolean> whenRecursiveReturn = { Statement statement, boolean inClosure ->
- if (!inClosure)
- return false
- if (!(statement instanceof ReturnStatement)) {
- return false
- }
- Expression inner = ((ReturnStatement )statement).expression
- if (!(inner instanceof MethodCallExpression) && !(inner instanceof StaticMethodCallExpression)) {
- return false
- }
- return isRecursiveIn(inner, method)
- }
- Closure<Statement> replaceWithThrowLoopException = { ReturnStatement statement ->
- new ReturnStatementToIterationConverter(recurStatement: AstHelper.recurByThrowStatement()).convert(statement, positionMapping)
- }
- StatementReplacer replacer = new StatementReplacer(when: whenRecursiveReturn, replaceWith: replaceWithThrowLoopException)
- replacer.replaceIn(method.code)
- }
-
- private void wrapMethodBodyWithWhileLoop(MethodNode method) {
- new InWhileLoopWrapper().wrap(method)
- }
-
- private void addMissingDefaultReturnStatement(MethodNode method) {
- new ReturnAdder().visitMethod(method)
- new ReturnAdderForClosures().visitMethod(method)
- }
-
- private void ensureAllRecursiveCallsHaveBeenTransformed(MethodNode method) {
- List<Expression> remainingRecursiveCalls = new CollectRecursiveCalls().collect(method)
- for(Expression expression : remainingRecursiveCalls) {
- addError("Recursive call could not be transformed by @TailRecursive. Maybe it's not a tail call.", expression)
- }
- }
-
- private boolean hasRecursiveMethodCalls(MethodNode method) {
- hasRecursiveCalls.test(method)
- }
-
- private boolean isRecursiveIn(Expression methodCall, MethodNode method) {
- if (methodCall instanceof MethodCallExpression)
- return new RecursivenessTester().isRecursive(method, (MethodCallExpression) methodCall)
- if (methodCall instanceof StaticMethodCallExpression)
- return new RecursivenessTester().isRecursive(method, (StaticMethodCallExpression) methodCall)
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/TernaryToIfStatementConverter.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/TernaryToIfStatementConverter.groovy b/src/main/groovy/TernaryToIfStatementConverter.groovy
deleted file mode 100644
index c47e1d2..0000000
--- a/src/main/groovy/TernaryToIfStatementConverter.groovy
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.codehaus.groovy.transform.tailrec
-
-import groovy.transform.CompileStatic
-import org.codehaus.groovy.ast.expr.TernaryExpression
-import org.codehaus.groovy.ast.stmt.IfStatement
-import org.codehaus.groovy.ast.stmt.ReturnStatement
-import org.codehaus.groovy.ast.stmt.Statement
-
-/**
- * Since a ternary statement has more than one exit point tail-recursiveness testing cannot be easily done.
- * Therefore this class translates a ternary statement (or Elvis operator) into the equivalent if-else statement.
- *
- * @author Johannes Link
- */
-@CompileStatic
-class TernaryToIfStatementConverter {
-
- Statement convert(ReturnStatement statementWithInnerTernaryExpression) {
- if (!(statementWithInnerTernaryExpression.expression instanceof TernaryExpression))
- return statementWithInnerTernaryExpression
- TernaryExpression ternary = statementWithInnerTernaryExpression.expression as TernaryExpression
- return new IfStatement(ternary.booleanExpression, new ReturnStatement(ternary.trueExpression), new ReturnStatement(ternary.falseExpression))
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/ThreadInterruptibleASTTransformation.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/ThreadInterruptibleASTTransformation.groovy b/src/main/groovy/ThreadInterruptibleASTTransformation.groovy
deleted file mode 100644
index a4fb4c3..0000000
--- a/src/main/groovy/ThreadInterruptibleASTTransformation.groovy
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.codehaus.groovy.transform
-
-import groovy.transform.CompileStatic
-import groovy.transform.ThreadInterrupt
-import org.codehaus.groovy.ast.ClassHelper
-import org.codehaus.groovy.ast.ClassNode
-import org.codehaus.groovy.ast.MethodNode
-import org.codehaus.groovy.ast.Parameter
-import org.codehaus.groovy.ast.expr.ArgumentListExpression
-import org.codehaus.groovy.ast.expr.ClassExpression
-import org.codehaus.groovy.ast.expr.ClosureExpression
-import org.codehaus.groovy.ast.expr.Expression
-import org.codehaus.groovy.ast.expr.MethodCallExpression
-import org.codehaus.groovy.control.CompilePhase
-
-/**
- * Allows "interrupt-safe" executions of scripts by adding Thread.currentThread().isInterrupted()
- * checks on loops (for, while, do) and first statement of closures. By default, also adds an interrupt check
- * statement on the beginning of method calls.
- *
- * @see groovy.transform.ThreadInterrupt
- *
- * @author Cedric Champeau
- * @author Hamlet D'Arcy
- *
- * @since 1.8.0
- */
-@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
-@CompileStatic
-public class ThreadInterruptibleASTTransformation extends AbstractInterruptibleASTTransformation {
-
- private static final ClassNode MY_TYPE = ClassHelper.make(ThreadInterrupt)
- private static final ClassNode THREAD_TYPE = ClassHelper.make(Thread)
- private static final MethodNode CURRENTTHREAD_METHOD
- private static final MethodNode ISINTERRUPTED_METHOD
-
- static {
- CURRENTTHREAD_METHOD = THREAD_TYPE.getMethod('currentThread', Parameter.EMPTY_ARRAY)
- ISINTERRUPTED_METHOD = THREAD_TYPE.getMethod('isInterrupted', Parameter.EMPTY_ARRAY)
- }
-
- protected ClassNode type() {
- return MY_TYPE;
- }
-
- protected String getErrorMessage() {
- 'Execution interrupted. The current thread has been interrupted.'
- }
-
- protected Expression createCondition() {
- def currentThread = new MethodCallExpression(new ClassExpression(THREAD_TYPE),
- 'currentThread',
- ArgumentListExpression.EMPTY_ARGUMENTS)
- currentThread.methodTarget = CURRENTTHREAD_METHOD
- def isInterrupted = new MethodCallExpression(
- currentThread,
- 'isInterrupted', ArgumentListExpression.EMPTY_ARGUMENTS)
- isInterrupted.methodTarget = ISINTERRUPTED_METHOD
- [currentThread, isInterrupted]*.implicitThis = false
-
- isInterrupted
- }
-
-
- @Override
- public void visitClosureExpression(ClosureExpression closureExpr) {
- def code = closureExpr.code
- closureExpr.code = wrapBlock(code)
- super.visitClosureExpression closureExpr
- }
-
- @Override
- public void visitMethod(MethodNode node) {
- if (checkOnMethodStart && !node.isSynthetic() && !node.isAbstract()) {
- def code = node.code
- node.code = wrapBlock(code);
- }
- super.visitMethod(node)
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/TimedInterruptibleASTTransformation.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/TimedInterruptibleASTTransformation.groovy b/src/main/groovy/TimedInterruptibleASTTransformation.groovy
deleted file mode 100644
index fbc923b..0000000
--- a/src/main/groovy/TimedInterruptibleASTTransformation.groovy
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.codehaus.groovy.transform
-
-import groovy.transform.TimedInterrupt
-import org.codehaus.groovy.ast.ASTNode
-import org.codehaus.groovy.ast.AnnotatedNode
-import org.codehaus.groovy.ast.AnnotationNode
-import org.codehaus.groovy.ast.ClassCodeVisitorSupport
-import org.codehaus.groovy.ast.ClassHelper
-import org.codehaus.groovy.ast.ClassNode
-import org.codehaus.groovy.ast.FieldNode
-import org.codehaus.groovy.ast.MethodNode
-import org.codehaus.groovy.ast.PropertyNode
-import org.codehaus.groovy.ast.expr.ClosureExpression
-import org.codehaus.groovy.ast.expr.ConstantExpression
-import org.codehaus.groovy.ast.expr.DeclarationExpression
-import org.codehaus.groovy.ast.expr.Expression
-import org.codehaus.groovy.ast.stmt.BlockStatement
-import org.codehaus.groovy.ast.stmt.DoWhileStatement
-import org.codehaus.groovy.ast.stmt.ForStatement
-import org.codehaus.groovy.ast.stmt.WhileStatement
-import org.codehaus.groovy.control.CompilePhase
-import org.codehaus.groovy.control.SourceUnit
-
-import java.util.concurrent.TimeUnit
-import java.util.concurrent.TimeoutException
-
-import static org.codehaus.groovy.ast.ClassHelper.make
-import static org.codehaus.groovy.ast.tools.GeneralUtils.args
-import static org.codehaus.groovy.ast.tools.GeneralUtils.callX
-import static org.codehaus.groovy.ast.tools.GeneralUtils.classX
-import static org.codehaus.groovy.ast.tools.GeneralUtils.constX
-import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorX
-import static org.codehaus.groovy.ast.tools.GeneralUtils.ifS
-import static org.codehaus.groovy.ast.tools.GeneralUtils.ltX
-import static org.codehaus.groovy.ast.tools.GeneralUtils.plusX
-import static org.codehaus.groovy.ast.tools.GeneralUtils.propX
-import static org.codehaus.groovy.ast.tools.GeneralUtils.throwS
-import static org.codehaus.groovy.ast.tools.GeneralUtils.varX
-
-/**
- * Allows "interrupt-safe" executions of scripts by adding timer expiration
- * checks on loops (for, while, do) and first statement of closures. By default,
- * also adds an interrupt check statement on the beginning of method calls.
- *
- * @author Cedric Champeau
- * @author Hamlet D'Arcy
- * @author Paul King
- * @see groovy.transform.ThreadInterrupt
- * @since 1.8.0
- */
-@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
-public class TimedInterruptibleASTTransformation extends AbstractASTTransformation {
-
- private static final ClassNode MY_TYPE = make(TimedInterrupt)
- private static final String CHECK_METHOD_START_MEMBER = 'checkOnMethodStart'
- private static final String APPLY_TO_ALL_CLASSES = 'applyToAllClasses'
- private static final String APPLY_TO_ALL_MEMBERS = 'applyToAllMembers'
- private static final String THROWN_EXCEPTION_TYPE = "thrown"
-
- public void visit(ASTNode[] nodes, SourceUnit source) {
- init(nodes, source);
- AnnotationNode node = nodes[0]
- AnnotatedNode annotatedNode = nodes[1]
- if (!MY_TYPE.equals(node.getClassNode())) {
- internalError("Transformation called from wrong annotation: $node.classNode.name")
- }
-
- def checkOnMethodStart = getConstantAnnotationParameter(node, CHECK_METHOD_START_MEMBER, Boolean.TYPE, true)
- def applyToAllMembers = getConstantAnnotationParameter(node, APPLY_TO_ALL_MEMBERS, Boolean.TYPE, true)
- def applyToAllClasses = applyToAllMembers ? getConstantAnnotationParameter(node, APPLY_TO_ALL_CLASSES, Boolean.TYPE, true) : false
- def maximum = getConstantAnnotationParameter(node, 'value', Long.TYPE, Long.MAX_VALUE)
- def thrown = AbstractInterruptibleASTTransformation.getClassAnnotationParameter(node, THROWN_EXCEPTION_TYPE, make(TimeoutException))
-
- Expression unit = node.getMember('unit') ?: propX(classX(TimeUnit), "SECONDS")
-
- // should be limited to the current SourceUnit or propagated to the whole CompilationUnit
- // DO NOT inline visitor creation in code below. It has state that must not persist between calls
- if (applyToAllClasses) {
- // guard every class and method defined in this script
- source.getAST()?.classes?.each { ClassNode it ->
- def visitor = new TimedInterruptionVisitor(source, checkOnMethodStart, applyToAllClasses, applyToAllMembers, maximum, unit, thrown, node.hashCode())
- visitor.visitClass(it)
- }
- } else if (annotatedNode instanceof ClassNode) {
- // only guard this particular class
- def visitor = new TimedInterruptionVisitor(source, checkOnMethodStart, applyToAllClasses, applyToAllMembers, maximum, unit, thrown, node.hashCode())
- visitor.visitClass annotatedNode
- } else if (!applyToAllMembers && annotatedNode instanceof MethodNode) {
- // only guard this particular method (plus initCode for class)
- def visitor = new TimedInterruptionVisitor(source, checkOnMethodStart, applyToAllClasses, applyToAllMembers, maximum, unit, thrown, node.hashCode())
- visitor.visitMethod annotatedNode
- visitor.visitClass annotatedNode.declaringClass
- } else if (!applyToAllMembers && annotatedNode instanceof FieldNode) {
- // only guard this particular field (plus initCode for class)
- def visitor = new TimedInterruptionVisitor(source, checkOnMethodStart, applyToAllClasses, applyToAllMembers, maximum, unit, thrown, node.hashCode())
- visitor.visitField annotatedNode
- visitor.visitClass annotatedNode.declaringClass
- } else if (!applyToAllMembers && annotatedNode instanceof DeclarationExpression) {
- // only guard this particular declaration (plus initCode for class)
- def visitor = new TimedInterruptionVisitor(source, checkOnMethodStart, applyToAllClasses, applyToAllMembers, maximum, unit, thrown, node.hashCode())
- visitor.visitDeclarationExpression annotatedNode
- visitor.visitClass annotatedNode.declaringClass
- } else {
- // only guard the script class
- source.getAST()?.classes?.each { ClassNode it ->
- if (it.isScript()) {
- def visitor = new TimedInterruptionVisitor(source, checkOnMethodStart, applyToAllClasses, applyToAllMembers, maximum, unit, thrown, node.hashCode())
- visitor.visitClass(it)
- }
- }
- }
- }
-
- static def getConstantAnnotationParameter(AnnotationNode node, String parameterName, Class type, defaultValue) {
- def member = node.getMember(parameterName)
- if (member) {
- if (member instanceof ConstantExpression) {
- // TODO not sure this try offers value - testing Groovy annotation type handing - throw GroovyBugError or remove?
- try {
- return member.value.asType(type)
- } catch (ignore) {
- internalError("Expecting boolean value for ${parameterName} annotation parameter. Found $member")
- }
- } else {
- internalError("Expecting boolean value for ${parameterName} annotation parameter. Found $member")
- }
- }
- return defaultValue
- }
-
- private static void internalError(String message) {
- throw new RuntimeException("Internal error: $message")
- }
-
- private static class TimedInterruptionVisitor extends ClassCodeVisitorSupport {
- final private SourceUnit source
- final private boolean checkOnMethodStart
- final private boolean applyToAllClasses
- final private boolean applyToAllMembers
- private FieldNode expireTimeField = null
- private FieldNode startTimeField = null
- private final Expression unit
- private final maximum
- private final ClassNode thrown
- private final String basename
-
- TimedInterruptionVisitor(source, checkOnMethodStart, applyToAllClasses, applyToAllMembers, maximum, unit, thrown, hash) {
- this.source = source
- this.checkOnMethodStart = checkOnMethodStart
- this.applyToAllClasses = applyToAllClasses
- this.applyToAllMembers = applyToAllMembers
- this.unit = unit
- this.maximum = maximum
- this.thrown = thrown
- this.basename = 'timedInterrupt' + hash
- }
-
- /**
- * @return Returns the interruption check statement.
- */
- final createInterruptStatement() {
- ifS(
-
- ltX(
- propX(varX("this"), basename + '$expireTime'),
- callX(make(System), 'nanoTime')
- ),
- throwS(
- ctorX(thrown,
- args(
- plusX(
- plusX(
- constX('Execution timed out after ' + maximum + ' '),
- callX(callX(unit, 'name'), 'toLowerCase', propX(classX(Locale), 'US'))
- ),
- plusX(
- constX('. Start time: '),
- propX(varX("this"), basename + '$startTime')
- )
- )
-
- )
- )
- )
- )
- }
-
- /**
- * Takes a statement and wraps it into a block statement which first element is the interruption check statement.
- * @param statement the statement to be wrapped
- * @return a {@link BlockStatement block statement} which first element is for checking interruption, and the
- * second one the statement to be wrapped.
- */
- private wrapBlock(statement) {
- def stmt = new BlockStatement();
- stmt.addStatement(createInterruptStatement());
- stmt.addStatement(statement);
- stmt
- }
-
- @Override
- void visitClass(ClassNode node) {
- if (node.getDeclaredField(basename + '$expireTime')) {
- return
- }
- expireTimeField = node.addField(basename + '$expireTime',
- ACC_FINAL | ACC_PRIVATE,
- ClassHelper.long_TYPE,
- plusX(
- callX(make(System), 'nanoTime'),
- callX(
- propX(classX(TimeUnit), 'NANOSECONDS'),
- 'convert',
- args(constX(maximum, true), unit)
- )
- )
- );
- expireTimeField.synthetic = true
- startTimeField = node.addField(basename + '$startTime',
- ACC_FINAL | ACC_PRIVATE,
- make(Date),
- ctorX(make(Date))
- )
- startTimeField.synthetic = true
-
- // force these fields to be initialized first
- node.fields.remove(expireTimeField)
- node.fields.remove(startTimeField)
- node.fields.add(0, startTimeField)
- node.fields.add(0, expireTimeField)
- if (applyToAllMembers) {
- super.visitClass node
- }
- }
-
- @Override
- void visitClosureExpression(ClosureExpression closureExpr) {
- def code = closureExpr.code
- if (code instanceof BlockStatement) {
- code.statements.add(0, createInterruptStatement())
- } else {
- closureExpr.code = wrapBlock(code)
- }
- super.visitClosureExpression closureExpr
- }
-
- @Override
- void visitField(FieldNode node) {
- if (!node.isStatic() && !node.isSynthetic()) {
- super.visitField node
- }
- }
-
- @Override
- void visitProperty(PropertyNode node) {
- if (!node.isStatic() && !node.isSynthetic()) {
- super.visitProperty node
- }
- }
-
- /**
- * Shortcut method which avoids duplicating code for every type of loop.
- * Actually wraps the loopBlock of different types of loop statements.
- */
- private visitLoop(loopStatement) {
- def statement = loopStatement.loopBlock
- loopStatement.loopBlock = wrapBlock(statement)
- }
-
- @Override
- void visitForLoop(ForStatement forStatement) {
- visitLoop(forStatement)
- super.visitForLoop(forStatement)
- }
-
- @Override
- void visitDoWhileLoop(final DoWhileStatement doWhileStatement) {
- visitLoop(doWhileStatement)
- super.visitDoWhileLoop(doWhileStatement)
- }
-
- @Override
- void visitWhileLoop(final WhileStatement whileStatement) {
- visitLoop(whileStatement)
- super.visitWhileLoop(whileStatement)
- }
-
- @Override
- void visitMethod(MethodNode node) {
- if (checkOnMethodStart && !node.isSynthetic() && !node.isStatic() && !node.isAbstract()) {
- def code = node.code
- node.code = wrapBlock(code);
- }
- if (!node.isSynthetic() && !node.isStatic()) {
- super.visitMethod(node)
- }
- }
-
- protected SourceUnit getSourceUnit() {
- return source;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/TransformTestHelper.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/TransformTestHelper.groovy b/src/main/groovy/TransformTestHelper.groovy
deleted file mode 100644
index d9921d5..0000000
--- a/src/main/groovy/TransformTestHelper.groovy
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.codehaus.groovy.tools.ast
-
-import org.codehaus.groovy.ast.ClassNode
-import org.codehaus.groovy.classgen.GeneratorContext
-import org.codehaus.groovy.control.CompilationUnit
-import org.codehaus.groovy.control.CompilationUnit.PrimaryClassNodeOperation
-import org.codehaus.groovy.control.CompilePhase
-import org.codehaus.groovy.control.CompilerConfiguration
-import org.codehaus.groovy.control.SourceUnit
-import org.codehaus.groovy.transform.ASTTransformation
-
-import java.security.CodeSource
-
-/*
-* This TestHarness exists so that a global transform can be run without
-* using the Jar services mechanism, which requires building a jar.
-*
-* To use this simply create an instance of TransformTestHelper with
-* an ASTTransformation and CompilePhase, then invoke parse(File) or
-* parse(String).
-*
-* This test harness is not exactly the same as executing a global transformation
-* but can greatly aide in debugging and testing a transform. You should still
-* test your global transformation when packaged as a jar service before
-* releasing it.
-*
-* @author Hamlet D'Arcy
-*/
-class TransformTestHelper {
-
- private final ASTTransformation transform
- private final CompilePhase phase
-
- /**
- * Creates the test helper.
- * @param transform
- * the transform to run when compiling the file later
- * @param phase
- * the phase to run the transform in
- */
- def TransformTestHelper(ASTTransformation transform, CompilePhase phase) {
- this.transform = transform
- this.phase = phase
- }
-
- /**
- * Compiles the File into a Class applying the transform specified in the constructor.
- * @input input
- * must be a groovy source file
- */
- public Class parse(File input) {
- TestHarnessClassLoader loader = new TestHarnessClassLoader(transform, phase)
- return loader.parseClass(input)
- }
-
- /**
- * Compiles the String into a Class applying the transform specified in the constructor.
- * @input input
- * must be a valid groovy source string
- */
- public Class parse(String input) {
- TestHarnessClassLoader loader = new TestHarnessClassLoader(transform, phase)
- return loader.parseClass(input)
- }
-}
-
-/**
-* ClassLoader exists so that TestHarnessOperation can be wired into the compile.
-*
-* @author Hamlet D'Arcy
-*/
-@groovy.transform.PackageScope class TestHarnessClassLoader extends GroovyClassLoader {
-
- private final ASTTransformation transform
- private final CompilePhase phase
-
- TestHarnessClassLoader(ASTTransformation transform, CompilePhase phase) {
- this.transform = transform
- this.phase = phase
- }
-
- protected CompilationUnit createCompilationUnit(CompilerConfiguration config, CodeSource codeSource) {
- CompilationUnit cu = super.createCompilationUnit(config, codeSource)
- cu.addPhaseOperation(new TestHarnessOperation(transform), phase.getPhaseNumber())
- return cu
- }
-}
-
-/**
-* Operation exists so that an AstTransformation can be run against the SourceUnit.
-*
-* @author Hamlet D'Arcy
-*/
-@groovy.transform.PackageScope class TestHarnessOperation extends PrimaryClassNodeOperation {
-
- private final ASTTransformation transform
-
- def TestHarnessOperation(transform) {
- this.transform = transform;
- }
-
- public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) {
- transform.visit(null, source)
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/VariableAccessReplacer.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/VariableAccessReplacer.groovy b/src/main/groovy/VariableAccessReplacer.groovy
deleted file mode 100644
index d62dc46..0000000
--- a/src/main/groovy/VariableAccessReplacer.groovy
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.codehaus.groovy.transform.tailrec
-
-import groovy.transform.CompileStatic
-import org.codehaus.groovy.ast.ASTNode
-import org.codehaus.groovy.ast.expr.VariableExpression
-
-/**
- * Replace all access to variables and args by new variables.
- * The variable names to replace as well as their replacement name and type have to be configured
- * in nameAndTypeMapping before calling replaceIn().
- *
- * The VariableReplacedListener can be set if clients want to react to variable replacement.
- *
- * @author Johannes Link
- */
-@CompileStatic
-class VariableAccessReplacer {
-
- /**
- * Nested map of variable accesses to replace
- * e.g.: [
- * 'varToReplace': [name: 'newVar', type: TypeOfVar],
- * 'varToReplace2': [name: 'newVar2', type: TypeOfVar2],
- * ]
- */
- Map<String, Map> nameAndTypeMapping = [:]
-
- VariableReplacedListener listener = VariableReplacedListener.NULL
-
- void replaceIn(ASTNode root) {
- Closure<Boolean> whenParam = { VariableExpression expr ->
- return nameAndTypeMapping.containsKey(expr.name)
- }
- Closure<VariableExpression> replaceWithLocalVariable = { VariableExpression expr ->
- Map nameAndType = nameAndTypeMapping[expr.name]
- VariableExpression newVar = AstHelper.createVariableReference(nameAndType)
- listener.variableReplaced(expr, newVar)
- return newVar
- }
- new VariableExpressionReplacer(when: whenParam, replaceWith: replaceWithLocalVariable).replaceIn(root)
- }
-
-}
-
-@CompileStatic
-interface VariableReplacedListener {
- void variableReplaced(VariableExpression oldVar, VariableExpression newVar)
-
- static VariableReplacedListener NULL = new VariableReplacedListener() {
- @Override
- void variableReplaced(VariableExpression oldVar, VariableExpression newVar) {
- //do nothing
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/VariableExpressionReplacer.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/VariableExpressionReplacer.groovy b/src/main/groovy/VariableExpressionReplacer.groovy
deleted file mode 100644
index 1f14490..0000000
--- a/src/main/groovy/VariableExpressionReplacer.groovy
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.codehaus.groovy.transform.tailrec
-
-import groovy.transform.CompileStatic
-import org.codehaus.groovy.ast.ASTNode
-import org.codehaus.groovy.ast.CodeVisitorSupport
-import org.codehaus.groovy.ast.expr.BinaryExpression
-import org.codehaus.groovy.ast.expr.BooleanExpression
-import org.codehaus.groovy.ast.expr.Expression
-import org.codehaus.groovy.ast.expr.ExpressionTransformer
-import org.codehaus.groovy.ast.expr.VariableExpression
-import org.codehaus.groovy.ast.stmt.AssertStatement
-import org.codehaus.groovy.ast.stmt.CaseStatement
-import org.codehaus.groovy.ast.stmt.DoWhileStatement
-import org.codehaus.groovy.ast.stmt.ExpressionStatement
-import org.codehaus.groovy.ast.stmt.ForStatement
-import org.codehaus.groovy.ast.stmt.IfStatement
-import org.codehaus.groovy.ast.stmt.ReturnStatement
-import org.codehaus.groovy.ast.stmt.SwitchStatement
-import org.codehaus.groovy.ast.stmt.SynchronizedStatement
-import org.codehaus.groovy.ast.stmt.ThrowStatement
-import org.codehaus.groovy.ast.stmt.WhileStatement
-
-import java.lang.reflect.Method
-
-/**
- * Tool for replacing VariableExpression instances in an AST by other VariableExpression instances.
- * Regardless of a real change taking place in nested expressions, all considered expression (trees) will be replaced.
- * This could be optimized to accelerate compilation.
- *
- * Within @TailRecursive it is used
- * - to swap the access of method args with the access to iteration variables
- * - to swap the access of iteration variables with the access of temp vars
- *
- * @author Johannes Link
- */
-@CompileStatic
-class VariableExpressionReplacer extends CodeVisitorSupport {
-
- Closure<Boolean> when = { VariableExpression node -> false }
- Closure<VariableExpression> replaceWith = { VariableExpression variableExpression -> variableExpression }
-
- private ExpressionTransformer transformer
-
- synchronized void replaceIn(ASTNode root) {
- transformer = new VariableExpressionTransformer(when: when, replaceWith: replaceWith)
- root.visit(this)
- }
-
- public void visitReturnStatement(ReturnStatement statement) {
- replaceExpressionPropertyWhenNecessary(statement)
- super.visitReturnStatement(statement);
- }
-
- public void visitIfElse(IfStatement ifElse) {
- replaceExpressionPropertyWhenNecessary(ifElse, 'booleanExpression', BooleanExpression)
- super.visitIfElse(ifElse);
- }
-
- public void visitForLoop(ForStatement forLoop) {
- replaceExpressionPropertyWhenNecessary(forLoop, 'collectionExpression')
- super.visitForLoop(forLoop);
- }
-
- /**
- * It's the only Expression type in which replacing is considered.
- * That's an abuse of the class, but I couldn't think of a better way.
- */
- public void visitBinaryExpression(BinaryExpression expression) {
- //A hack: Only replace right expression b/c ReturnStatementToIterationConverter needs it that way :-/
- replaceExpressionPropertyWhenNecessary(expression, 'rightExpression')
- expression.getRightExpression().visit(this);
- super.visitBinaryExpression(expression)
- }
-
- public void visitWhileLoop(WhileStatement loop) {
- replaceExpressionPropertyWhenNecessary(loop, 'booleanExpression', BooleanExpression)
- super.visitWhileLoop(loop);
- }
-
- public void visitDoWhileLoop(DoWhileStatement loop) {
- replaceExpressionPropertyWhenNecessary(loop, 'booleanExpression', BooleanExpression)
- super.visitDoWhileLoop(loop);
- }
-
- public void visitSwitch(SwitchStatement statement) {
- replaceExpressionPropertyWhenNecessary(statement)
- super.visitSwitch(statement)
- }
-
- public void visitCaseStatement(CaseStatement statement) {
- replaceExpressionPropertyWhenNecessary(statement)
- super.visitCaseStatement(statement)
- }
-
- public void visitExpressionStatement(ExpressionStatement statement) {
- replaceExpressionPropertyWhenNecessary(statement)
- super.visitExpressionStatement(statement);
- }
-
- public void visitThrowStatement(ThrowStatement statement) {
- replaceExpressionPropertyWhenNecessary(statement)
- super.visitThrowStatement(statement)
- }
-
- public void visitAssertStatement(AssertStatement statement) {
- replaceExpressionPropertyWhenNecessary(statement, 'booleanExpression', BooleanExpression)
- replaceExpressionPropertyWhenNecessary(statement, 'messageExpression')
- super.visitAssertStatement(statement)
- }
-
- public void visitSynchronizedStatement(SynchronizedStatement statement) {
- replaceExpressionPropertyWhenNecessary(statement)
- super.visitSynchronizedStatement(statement)
- }
-
- private void replaceExpressionPropertyWhenNecessary(ASTNode node, String propName = "expression", Class propClass = Expression) {
- Expression expr = getExpression(node, propName)
-
- if (expr instanceof VariableExpression) {
- if (when(expr)) {
- VariableExpression newExpr = replaceWith(expr)
- replaceExpression(node, propName, propClass, expr, newExpr)
- }
- } else {
- Expression newExpr = expr.transformExpression(transformer)
- replaceExpression(node, propName, propClass, expr, newExpr)
- }
- }
-
- private void replaceExpression(ASTNode node, String propName, Class propClass, Expression oldExpr, Expression newExpr) {
- //Use reflection to enable CompileStatic
- String setterName = 'set' + capitalizeFirst(propName)
- Method setExpressionMethod = node.class.getMethod(setterName, [propClass].toArray(new Class[1]))
- newExpr.setSourcePosition(oldExpr);
- newExpr.copyNodeMetaData(oldExpr);
- setExpressionMethod.invoke(node, [newExpr].toArray())
- }
-
- private Expression getExpression(ASTNode node, String propName) {
- //Use reflection to enable CompileStatic
- String getterName = 'get' + capitalizeFirst(propName)
- Method getExpressionMethod = node.class.getMethod(getterName, new Class[0])
- getExpressionMethod.invoke(node, new Object[0]) as Expression
- }
-
- private String capitalizeFirst(String propName) {
- propName[0].toUpperCase() + propName[1..-1]
- }
-
-
-}
-
-
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/VariableExpressionTransformer.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/VariableExpressionTransformer.groovy b/src/main/groovy/VariableExpressionTransformer.groovy
deleted file mode 100644
index 106a2f1..0000000
--- a/src/main/groovy/VariableExpressionTransformer.groovy
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.codehaus.groovy.transform.tailrec
-
-import groovy.transform.CompileStatic
-import org.codehaus.groovy.ast.expr.Expression
-import org.codehaus.groovy.ast.expr.ExpressionTransformer
-import org.codehaus.groovy.ast.expr.VariableExpression
-
-/**
- * An expression transformer used in the process of replacing the access to variables
- *
- * @author Johannes Link
- */
-@CompileStatic
-class VariableExpressionTransformer implements ExpressionTransformer {
-
- Closure<Boolean> when
- Closure<VariableExpression> replaceWith
-
- @Override
- Expression transform(Expression expr) {
- if ((expr instanceof VariableExpression) && when(expr)) {
- VariableExpression newExpr = replaceWith(expr)
- newExpr.setSourcePosition(expr);
- newExpr.copyNodeMetaData(expr);
- return newExpr
- }
- return expr.transformExpression(this)
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/beans/Bindable.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/beans/Bindable.java b/src/main/groovy/beans/Bindable.java
deleted file mode 100644
index cf0a5c9..0000000
--- a/src/main/groovy/beans/Bindable.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 groovy.beans;
-
-import org.codehaus.groovy.transform.GroovyASTTransformationClass;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotates a groovy property or a class.
- *
- * When annotating a property it indicates that the property should be a
- * bound property according to the JavaBeans spec, announcing to listeners
- * that the value has changed.
- * <p>
- * When annotating a class it indicates that all groovy properties in that
- * class should be bound as though each property had the annotation (even
- * if it already has it explicitly).
- * <p>
- * It is a compilation error to place this annotation on a field (that is
- * not a property, i.e. has scope visibility modifiers).
- * <p>
- * If a property with a user defined setter method is annotated the code
- * block is wrapped with the needed code to fire off the event.
- * <p>
- * The following example shows how you can use this annotation on fields
- * of a class:
- * <pre>
- * class Person {
- * @groovy.beans.Bindable
- * String firstName
- *
- * @groovy.beans.Bindable
- * def zipCode
- * }
- * </pre>
- * The above example will generate code that is similar to the next snippet.
- * Notice the difference between a String property and a def/Object property:
- * <pre>
- * public class Person {
- * @groovy.beans.Bindable
- * private java.lang.String firstName
- * @groovy.beans.Bindable
- * private java.lang.Object zipCode
- * final private java.beans.PropertyChangeSupport this$propertyChangeSupport
- *
- * public Person() {
- * this$propertyChangeSupport = new java.beans.PropertyChangeSupport(this)
- * }
- *
- * public void addPropertyChangeListener(java.beans.PropertyChangeListener listener) {
- * this$propertyChangeSupport.addPropertyChangeListener(listener)
- * }
- *
- * public void addPropertyChangeListener(java.lang.String name, java.beans.PropertyChangeListener listener) {
- * this$propertyChangeSupport.addPropertyChangeListener(name, listener)
- * }
- *
- * public void removePropertyChangeListener(java.beans.PropertyChangeListener listener) {
- * this$propertyChangeSupport.removePropertyChangeListener(listener)
- * }
- *
- * public void removePropertyChangeListener(java.lang.String name, java.beans.PropertyChangeListener listener) {
- * this$propertyChangeSupport.removePropertyChangeListener(name, listener)
- * }
- *
- * public void firePropertyChange(java.lang.String name, java.lang.Object oldValue, java.lang.Object newValue) {
- * this$propertyChangeSupport.firePropertyChange(name, oldValue, newValue)
- * }
- *
- * public java.beans.PropertyChangeListener[] getPropertyChangeListeners() {
- * return this$propertyChangeSupport.getPropertyChangeListeners()
- * }
- *
- * public java.beans.PropertyChangeListener[] getPropertyChangeListeners(java.lang.String name) {
- * return this$propertyChangeSupport.getPropertyChangeListeners(name)
- * }
- *
- * public void setFirstName(java.lang.String value) {
- * this.firePropertyChange('firstName', firstName, firstName = value )
- * }
- *
- * public void setZipCode(java.lang.Object value) {
- * this.firePropertyChange('zipCode', zipCode, zipCode = value )
- * }
- * }
- * </pre>
- *
- * @see BindableASTTransformation
- * @author Danno Ferrin (shemnon)
- */
-@java.lang.annotation.Documented
-@Retention(RetentionPolicy.SOURCE)
-@Target({ElementType.FIELD, ElementType.TYPE})
-@GroovyASTTransformationClass("groovy.beans.BindableASTTransformation")
-public @interface Bindable {
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/beans/BindableASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/beans/BindableASTTransformation.java b/src/main/groovy/beans/BindableASTTransformation.java
deleted file mode 100644
index f987295..0000000
--- a/src/main/groovy/beans/BindableASTTransformation.java
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 groovy.beans;
-
-import org.codehaus.groovy.ast.ASTNode;
-import org.codehaus.groovy.ast.AnnotatedNode;
-import org.codehaus.groovy.ast.AnnotationNode;
-import org.codehaus.groovy.ast.ClassHelper;
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.FieldNode;
-import org.codehaus.groovy.ast.MethodNode;
-import org.codehaus.groovy.ast.Parameter;
-import org.codehaus.groovy.ast.PropertyNode;
-import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.ast.stmt.BlockStatement;
-import org.codehaus.groovy.ast.stmt.Statement;
-import org.codehaus.groovy.ast.tools.PropertyNodeUtils;
-import org.codehaus.groovy.control.CompilePhase;
-import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.control.messages.SimpleMessage;
-import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
-import org.codehaus.groovy.runtime.MetaClassHelper;
-import org.codehaus.groovy.syntax.SyntaxException;
-import org.codehaus.groovy.transform.ASTTransformation;
-import org.codehaus.groovy.transform.GroovyASTTransformation;
-import org.objectweb.asm.Opcodes;
-
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
-
-import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.assignX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.callThisX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.callX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.constX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.declS;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.fieldX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.param;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.params;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.returnS;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
-
-/**
- * Handles generation of code for the {@code @Bindable} annotation when {@code @Vetoable}
- * is not present.
- * <p>
- * Generally, it adds (if needed) a PropertyChangeSupport field and
- * the needed add/removePropertyChangeListener methods to support the
- * listeners.
- * <p>
- * It also generates the setter and wires the setter through the
- * PropertyChangeSupport.
- * <p>
- * If a {@link Vetoable} annotation is detected it does nothing and
- * lets the {@link VetoableASTTransformation} handle all the changes.
- *
- * @author Danno Ferrin (shemnon)
- * @author Chris Reeves
- */
-@GroovyASTTransformation(phase= CompilePhase.CANONICALIZATION)
-public class BindableASTTransformation implements ASTTransformation, Opcodes {
-
- protected static ClassNode boundClassNode = ClassHelper.make(Bindable.class);
-
- /**
- * Convenience method to see if an annotated node is {@code @Bindable}.
- *
- * @param node the node to check
- * @return true if the node is bindable
- */
- public static boolean hasBindableAnnotation(AnnotatedNode node) {
- for (AnnotationNode annotation : node.getAnnotations()) {
- if (boundClassNode.equals(annotation.getClassNode())) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Handles the bulk of the processing, mostly delegating to other methods.
- *
- * @param nodes the ast nodes
- * @param source the source unit for the nodes
- */
- public void visit(ASTNode[] nodes, SourceUnit source) {
- if (!(nodes[0] instanceof AnnotationNode) || !(nodes[1] instanceof AnnotatedNode)) {
- throw new RuntimeException("Internal error: wrong types: $node.class / $parent.class");
- }
- AnnotationNode node = (AnnotationNode) nodes[0];
- AnnotatedNode parent = (AnnotatedNode) nodes[1];
-
- if (VetoableASTTransformation.hasVetoableAnnotation(parent)) {
- // VetoableASTTransformation will handle both @Bindable and @Vetoable
- return;
- }
-
- ClassNode declaringClass = parent.getDeclaringClass();
- if (parent instanceof FieldNode) {
- if ((((FieldNode) parent).getModifiers() & Opcodes.ACC_FINAL) != 0) {
- source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage(
- new SyntaxException("@groovy.beans.Bindable cannot annotate a final property.",
- node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()),
- source));
- }
-
- if (VetoableASTTransformation.hasVetoableAnnotation(parent.getDeclaringClass())) {
- // VetoableASTTransformation will handle both @Bindable and @Vetoable
- return;
- }
- addListenerToProperty(source, node, declaringClass, (FieldNode) parent);
- } else if (parent instanceof ClassNode) {
- addListenerToClass(source, (ClassNode) parent);
- }
- }
-
- private void addListenerToProperty(SourceUnit source, AnnotationNode node, ClassNode declaringClass, FieldNode field) {
- String fieldName = field.getName();
- for (PropertyNode propertyNode : declaringClass.getProperties()) {
- if (propertyNode.getName().equals(fieldName)) {
- if (field.isStatic()) {
- //noinspection ThrowableInstanceNeverThrown
- source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage(
- new SyntaxException("@groovy.beans.Bindable cannot annotate a static property.",
- node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()),
- source));
- } else {
- if (needsPropertyChangeSupport(declaringClass, source)) {
- addPropertyChangeSupport(declaringClass);
- }
- createListenerSetter(declaringClass, propertyNode);
- }
- return;
- }
- }
- //noinspection ThrowableInstanceNeverThrown
- source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage(
- new SyntaxException("@groovy.beans.Bindable must be on a property, not a field. Try removing the private, protected, or public modifier.",
- node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()),
- source));
- }
-
- private void addListenerToClass(SourceUnit source, ClassNode classNode) {
- if (needsPropertyChangeSupport(classNode, source)) {
- addPropertyChangeSupport(classNode);
- }
- for (PropertyNode propertyNode : classNode.getProperties()) {
- FieldNode field = propertyNode.getField();
- // look to see if per-field handlers will catch this one...
- if (hasBindableAnnotation(field)
- || ((field.getModifiers() & Opcodes.ACC_FINAL) != 0)
- || field.isStatic()
- || VetoableASTTransformation.hasVetoableAnnotation(field))
- {
- // explicitly labeled properties are already handled,
- // don't transform final properties
- // don't transform static properties
- // VetoableASTTransformation will handle both @Bindable and @Vetoable
- continue;
- }
- createListenerSetter(classNode, propertyNode);
- }
- }
-
- /*
- * Wrap an existing setter.
- */
- private static void wrapSetterMethod(ClassNode classNode, String propertyName) {
- String getterName = "get" + MetaClassHelper.capitalize(propertyName);
- MethodNode setter = classNode.getSetterMethod("set" + MetaClassHelper.capitalize(propertyName));
-
- if (setter != null) {
- // Get the existing code block
- Statement code = setter.getCode();
-
- Expression oldValue = varX("$oldValue");
- Expression newValue = varX("$newValue");
- BlockStatement block = new BlockStatement();
-
- // create a local variable to hold the old value from the getter
- block.addStatement(declS(oldValue, callThisX(getterName)));
-
- // call the existing block, which will presumably set the value properly
- block.addStatement(code);
-
- // get the new value to emit in the event
- block.addStatement(declS(newValue, callThisX(getterName)));
-
- // add the firePropertyChange method call
- block.addStatement(stmt(callThisX("firePropertyChange", args(constX(propertyName), oldValue, newValue))));
-
- // replace the existing code block with our new one
- setter.setCode(block);
- }
- }
-
- private void createListenerSetter(ClassNode classNode, PropertyNode propertyNode) {
- String setterName = "set" + MetaClassHelper.capitalize(propertyNode.getName());
- if (classNode.getMethods(setterName).isEmpty()) {
- Statement setterBlock = createBindableStatement(propertyNode, fieldX(propertyNode.getField()));
-
- // create method void <setter>(<type> fieldName)
- createSetterMethod(classNode, propertyNode, setterName, setterBlock);
- } else {
- wrapSetterMethod(classNode, propertyNode.getName());
- }
- }
-
- /**
- * Creates a statement body similar to:
- * <code>this.firePropertyChange("field", field, field = value)</code>
- *
- * @param propertyNode the field node for the property
- * @param fieldExpression a field expression for setting the property value
- * @return the created statement
- */
- protected Statement createBindableStatement(PropertyNode propertyNode, Expression fieldExpression) {
- // create statementBody
- return stmt(callThisX("firePropertyChange", args(constX(propertyNode.getName()), fieldExpression, assignX(fieldExpression, varX("value")))));
- }
-
- /**
- * Creates a setter method with the given body.
- *
- * @param declaringClass the class to which we will add the setter
- * @param propertyNode the field to back the setter
- * @param setterName the name of the setter
- * @param setterBlock the statement representing the setter block
- */
- protected void createSetterMethod(ClassNode declaringClass, PropertyNode propertyNode, String setterName, Statement setterBlock) {
- MethodNode setter = new MethodNode(
- setterName,
- PropertyNodeUtils.adjustPropertyModifiersForMethod(propertyNode),
- ClassHelper.VOID_TYPE,
- params(param(propertyNode.getType(), "value")),
- ClassNode.EMPTY_ARRAY,
- setterBlock);
- setter.setSynthetic(true);
- // add it to the class
- declaringClass.addMethod(setter);
- }
-
- /**
- * Snoops through the declaring class and all parents looking for methods
- * <code>void addPropertyChangeListener(PropertyChangeListener)</code>,
- * <code>void removePropertyChangeListener(PropertyChangeListener)</code>, and
- * <code>void firePropertyChange(String, Object, Object)</code>. If any are defined all
- * must be defined or a compilation error results.
- *
- * @param declaringClass the class to search
- * @param sourceUnit the source unit, for error reporting. {@code @NotNull}.
- * @return true if property change support should be added
- */
- protected boolean needsPropertyChangeSupport(ClassNode declaringClass, SourceUnit sourceUnit) {
- boolean foundAdd = false, foundRemove = false, foundFire = false;
- ClassNode consideredClass = declaringClass;
- while (consideredClass!= null) {
- for (MethodNode method : consideredClass.getMethods()) {
- // just check length, MOP will match it up
- foundAdd = foundAdd || method.getName().equals("addPropertyChangeListener") && method.getParameters().length == 1;
- foundRemove = foundRemove || method.getName().equals("removePropertyChangeListener") && method.getParameters().length == 1;
- foundFire = foundFire || method.getName().equals("firePropertyChange") && method.getParameters().length == 3;
- if (foundAdd && foundRemove && foundFire) {
- return false;
- }
- }
- consideredClass = consideredClass.getSuperClass();
- }
- // check if a super class has @Bindable annotations
- consideredClass = declaringClass.getSuperClass();
- while (consideredClass!=null) {
- if (hasBindableAnnotation(consideredClass)) return false;
- for (FieldNode field : consideredClass.getFields()) {
- if (hasBindableAnnotation(field)) return false;
- }
- consideredClass = consideredClass.getSuperClass();
- }
- if (foundAdd || foundRemove || foundFire) {
- sourceUnit.getErrorCollector().addErrorAndContinue(
- new SimpleMessage("@Bindable cannot be processed on "
- + declaringClass.getName()
- + " because some but not all of addPropertyChangeListener, removePropertyChange, and firePropertyChange were declared in the current or super classes.",
- sourceUnit)
- );
- return false;
- }
- return true;
- }
-
- /**
- * Adds the necessary field and methods to support property change support.
- * <p>
- * Adds a new field:
- * <pre>
- * <code>protected final java.beans.PropertyChangeSupport this$PropertyChangeSupport = new java.beans.PropertyChangeSupport(this)</code>"
- * </pre>
- * <p>
- * Also adds support methods:
- * <pre>
- * <code>public void addPropertyChangeListener(java.beans.PropertyChangeListener)</code>
- * <code>public void addPropertyChangeListener(String, java.beans.PropertyChangeListener)</code>
- * <code>public void removePropertyChangeListener(java.beans.PropertyChangeListener)</code>
- * <code>public void removePropertyChangeListener(String, java.beans.PropertyChangeListener)</code>
- * <code>public java.beans.PropertyChangeListener[] getPropertyChangeListeners()</code>
- * </pre>
- *
- * @param declaringClass the class to which we add the support field and methods
- */
- protected void addPropertyChangeSupport(ClassNode declaringClass) {
- ClassNode pcsClassNode = ClassHelper.make(PropertyChangeSupport.class);
- ClassNode pclClassNode = ClassHelper.make(PropertyChangeListener.class);
- //String pcsFieldName = "this$propertyChangeSupport";
-
- // add field:
- // protected final PropertyChangeSupport this$propertyChangeSupport = new java.beans.PropertyChangeSupport(this)
- FieldNode pcsField = declaringClass.addField(
- "this$propertyChangeSupport",
- ACC_FINAL | ACC_PRIVATE | ACC_SYNTHETIC,
- pcsClassNode,
- ctorX(pcsClassNode, args(varX("this"))));
-
- // add method:
- // void addPropertyChangeListener(listener) {
- // this$propertyChangeSupport.addPropertyChangeListener(listener)
- // }
- declaringClass.addMethod(
- new MethodNode(
- "addPropertyChangeListener",
- ACC_PUBLIC,
- ClassHelper.VOID_TYPE,
- params(param(pclClassNode, "listener")),
- ClassNode.EMPTY_ARRAY,
- stmt(callX(fieldX(pcsField), "addPropertyChangeListener", args(varX("listener", pclClassNode))))));
-
- // add method:
- // void addPropertyChangeListener(name, listener) {
- // this$propertyChangeSupport.addPropertyChangeListener(name, listener)
- // }
- declaringClass.addMethod(
- new MethodNode(
- "addPropertyChangeListener",
- ACC_PUBLIC,
- ClassHelper.VOID_TYPE,
- params(param(ClassHelper.STRING_TYPE, "name"), param(pclClassNode, "listener")),
- ClassNode.EMPTY_ARRAY,
- stmt(callX(fieldX(pcsField), "addPropertyChangeListener", args(varX("name", ClassHelper.STRING_TYPE), varX("listener", pclClassNode))))));
-
- // add method:
- // boolean removePropertyChangeListener(listener) {
- // return this$propertyChangeSupport.removePropertyChangeListener(listener);
- // }
- declaringClass.addMethod(
- new MethodNode(
- "removePropertyChangeListener",
- ACC_PUBLIC,
- ClassHelper.VOID_TYPE,
- params(param(pclClassNode, "listener")),
- ClassNode.EMPTY_ARRAY,
- stmt(callX(fieldX(pcsField), "removePropertyChangeListener", args(varX("listener", pclClassNode))))));
-
- // add method: void removePropertyChangeListener(name, listener)
- declaringClass.addMethod(
- new MethodNode(
- "removePropertyChangeListener",
- ACC_PUBLIC,
- ClassHelper.VOID_TYPE,
- params(param(ClassHelper.STRING_TYPE, "name"), param(pclClassNode, "listener")),
- ClassNode.EMPTY_ARRAY,
- stmt(callX(fieldX(pcsField), "removePropertyChangeListener", args(varX("name", ClassHelper.STRING_TYPE), varX("listener", pclClassNode))))));
-
- // add method:
- // void firePropertyChange(String name, Object oldValue, Object newValue) {
- // this$propertyChangeSupport.firePropertyChange(name, oldValue, newValue)
- // }
- declaringClass.addMethod(
- new MethodNode(
- "firePropertyChange",
- ACC_PUBLIC,
- ClassHelper.VOID_TYPE,
- params(param(ClassHelper.STRING_TYPE, "name"), param(ClassHelper.OBJECT_TYPE, "oldValue"), param(ClassHelper.OBJECT_TYPE, "newValue")),
- ClassNode.EMPTY_ARRAY,
- stmt(callX(fieldX(pcsField), "firePropertyChange", args(varX("name", ClassHelper.STRING_TYPE), varX("oldValue"), varX("newValue"))))));
-
- // add method:
- // PropertyChangeListener[] getPropertyChangeListeners() {
- // return this$propertyChangeSupport.getPropertyChangeListeners
- // }
- declaringClass.addMethod(
- new MethodNode(
- "getPropertyChangeListeners",
- ACC_PUBLIC,
- pclClassNode.makeArray(),
- Parameter.EMPTY_ARRAY,
- ClassNode.EMPTY_ARRAY,
- returnS(callX(fieldX(pcsField), "getPropertyChangeListeners"))));
-
- // add method:
- // PropertyChangeListener[] getPropertyChangeListeners(String name) {
- // return this$propertyChangeSupport.getPropertyChangeListeners(name)
- // }
- declaringClass.addMethod(
- new MethodNode(
- "getPropertyChangeListeners",
- ACC_PUBLIC,
- pclClassNode.makeArray(),
- params(param(ClassHelper.STRING_TYPE, "name")),
- ClassNode.EMPTY_ARRAY,
- returnS(callX(fieldX(pcsField), "getPropertyChangeListeners", args(varX("name", ClassHelper.STRING_TYPE))))));
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/beans/DefaultPropertyAccessor.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/beans/DefaultPropertyAccessor.java b/src/main/groovy/beans/DefaultPropertyAccessor.java
deleted file mode 100644
index 47dae41..0000000
--- a/src/main/groovy/beans/DefaultPropertyAccessor.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 groovy.beans;
-
-/**
- * @author Andres Almiray
- */
-public class DefaultPropertyAccessor implements PropertyAccessor {
- public static final PropertyAccessor INSTANCE = new DefaultPropertyAccessor();
-
- public Object read(Object owner, String propertyName) {
- return DefaultPropertyReader.INSTANCE.read(owner, propertyName);
- }
-
- public void write(Object owner, String propertyName, Object value) {
- DefaultPropertyWriter.INSTANCE.write(owner, propertyName, value);
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/beans/DefaultPropertyReader.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/beans/DefaultPropertyReader.java b/src/main/groovy/beans/DefaultPropertyReader.java
deleted file mode 100644
index a03b9a3..0000000
--- a/src/main/groovy/beans/DefaultPropertyReader.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 groovy.beans;
-
-import org.codehaus.groovy.runtime.InvokerHelper;
-
-/**
- * @author Andres Almiray
- */
-public class DefaultPropertyReader implements PropertyReader {
- public static final PropertyReader INSTANCE = new DefaultPropertyReader();
-
- public Object read(Object owner, String propertyName) {
- return InvokerHelper.getPropertySafe(owner, propertyName);
- }
-}