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

org.netbeans.lib.nbjavac.services.NBAttr Maven / Gradle / Ivy

There is a newer version: RELEASE230
Show newest version
/*
 * 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.netbeans.lib.nbjavac.services;

import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.comp.Attr;
import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCBlock;
import com.sun.tools.javac.tree.JCTree.JCCatch;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCStringTemplate;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;

/**
 *
 * @author lahvac
 */
public class NBAttr extends Attr {

    public static boolean TEST_DO_SINGLE_FAIL;

    public static void preRegister(Context context) {
        context.put(attrKey, new Context.Factory() {
            public Attr make(Context c) {
                return new NBAttr(c);
            }
        });
    }

    private final CancelService cancelService;
    private final NBResolve rs;
    private final TreeMaker tm;

    public NBAttr(Context context) {
        super(context);
        cancelService = CancelService.instance(context);
        rs = NBResolve.instance(context);
        tm = TreeMaker.instance(context);
    }

    @Override
    public void attribClass(DiagnosticPosition pos, ClassSymbol c) {
        cancelService.abortIfCanceled();
        if (TEST_DO_SINGLE_FAIL) {
            TEST_DO_SINGLE_FAIL = false;
            throw new AssertionError("Test requested failure");
        }
        super.attribClass(pos, c);
    }

    @Override
    public void visitClassDef(JCClassDecl tree) {
        cancelService.abortIfCanceled();
        super.visitClassDef(tree);
    }

    @Override
    public void visitMethodDef(JCMethodDecl tree) {
        cancelService.abortIfCanceled();
        super.visitMethodDef(tree);
    }

    @Override
    public void visitBlock(JCBlock tree) {
        cancelService.abortIfCanceled();
        super.visitBlock(tree);
    }

    @Override
    public void visitVarDef(JCVariableDecl tree) {
        //for erroneous "var", make sure the synthetic make.Error() has an invalid/synthetic position:
        tm.at(-1);
        super.visitVarDef(tree);
    }

    @Override
    public Type attribType(JCTree tree, Env env) {
        cancelService.abortIfCanceled();
        return super.attribType(tree, env);
    }

    @Override
    public void visitCatch(JCCatch that) {
        super.visitBlock(tm.Block(0, List.of(that.param, that.body)));
    }

    @Override
    public void visitStringTemplate(JCStringTemplate tree) {
        //workaround for:
        //a) crash when tree.processor is null
        //b) crash when the StringTemplate.process method does not exist
        //should be removed when javac is improved to be more resilient w.r.t. these errors:
        boolean prevInStringTemplate = rs.inStringTemplate;
        try {
            if (tree.processor == null) {
                tree.processor = tm.Erroneous();
            }
            rs.inStringTemplate = true;
            super.visitStringTemplate(tree);
        } finally {
            rs.inStringTemplate = prevInStringTemplate;
        }
    }

    private boolean fullyAttribute;
    private Env fullyAttributeResult;

    protected void breakTreeFound(Env env) {
        if (fullyAttribute) {
            fullyAttributeResult = env;
        } else {
            try {
                MethodHandles.lookup()
                             .findSpecial(Attr.class, "breakTreeFound", MethodType.methodType(void.class, Env.class), NBAttr.class)
                             .invokeExact(this, env);
            } catch (Throwable ex) {
                sneakyThrows(ex);
            }
        }
    }

    protected void breakTreeFound(Env env, Type result) {
        if (fullyAttribute) {
            fullyAttributeResult = env;
        } else {
            try {
                MethodHandles.lookup()
                             .findSpecial(Attr.class, "breakTreeFound", MethodType.methodType(void.class, Env.class, Type.class), NBAttr.class)
                             .invokeExact(this, env, result);
            } catch (Throwable ex) {
                sneakyThrows(ex);
            }
        }
    }

    private  void sneakyThrows(Throwable t) throws T {
        throw (T) t;
    }

    public Env attributeAndCapture(JCTree tree, Env env, JCTree to) {
        try {
            fullyAttribute = true;

            Env result = tree instanceof JCExpression ?
                    attribExprToTree((JCExpression) tree, env, to) :
                    attribStatToTree(tree, env, to);

            return fullyAttributeResult != null ? fullyAttributeResult : result;
        } finally {
            fullyAttribute = false;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy