/*
 * Copyright 2020 the original author or authors.
 *
 * 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 org.codenarc.rule

import groovy.transform.InheritConstructors
import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.ast.ConstructorNode
import org.codehaus.groovy.ast.MethodNode

/**
 * AstVisitor that check for references to fields outside of constructors
 */
@InheritConstructors
class ConstructorsSkippingFieldReferenceAstVisitor extends FieldReferenceAstVisitor {

    private final Deque<ASTNode> methodContextStack = [] as Queue

    private ASTNode getMethodContext() {
        return methodContextStack.isEmpty() ? null : methodContextStack.peek()
    }

    @Override
    protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) {
        methodContextStack.push(node)
        super.visitConstructorOrMethod(node, isConstructor)
        methodContextStack.pop()
    }

    @Override
    protected void fieldReferenced(String name) {
        if (!(methodContext instanceof ConstructorNode)) {
            super.fieldReferenced(name)
        }
    }
}

/*
 * Copyright 2020 the original author or authors.
 *
 * 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 org.codenarc.rule

import groovy.transform.InheritConstructors
import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.ast.ConstructorNode
import org.codehaus.groovy.ast.MethodNode

/**
 * AstVisitor that checks for references to fields outside of constructors
 */
@InheritConstructors
class ConstructorsSkippingFieldReferenceAstVisitor extends FieldReferenceAstVisitor {

    private final Deque<ASTNode> methodContextStack = [] as Queue

    private ASTNode getMethodContext() {
        return methodContextStack.isEmpty() ? null : methodContextStack.peek()
    }

    @Override
    protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) {
        methodContextStack.push(node)
        super.visitConstructorOrMethod(node, isConstructor)
        methodContextStack.pop()
    }

    @Override
    protected void fieldReferenced(String name) {
        if (!(methodContext instanceof ConstructorNode)) {
            super.fieldReferenced(name)
        }
    }
}

Fix a typo in javadoc
Fix a typo in javadoc
