alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 *
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 *
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2002 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.javacore.parser;

import java.lang.ref.Reference;
import java.util.*;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.jmi.javamodel.ClassDefinition;
import org.netbeans.jmi.javamodel.Import;
import org.netbeans.jmi.javamodel.JavaClass;
import org.netbeans.jmi.javamodel.JavaModelPackage;
import org.netbeans.jmi.javamodel.ParameterizedType;
import org.netbeans.jmi.javamodel.Resource;
import org.netbeans.jmi.javamodel.UnresolvedClass;

import org.netbeans.lib.java.parser.ASTree;
import org.netbeans.modules.javacore.JMManager;
import org.netbeans.modules.javacore.jmiimpl.javamodel.JavaClassClassImpl;

/**
 *
 * @author  thurka
 */
public class Scope implements ScopeMember {
    
    private Scope parentScope;
    private Map positiveCache;
    private Set negativeCache;
    private ArrayList members;
    
    /** Creates a new instance of Scope */
    Scope(Scope parent) {
        parentScope=parent;
        positiveCache=new HashMap();
        negativeCache=new HashSet();
        members=new ArrayList();
    }
    
    public Object lookup(final Object key) {
        Object val=positiveCache.get(key);
        if (val!=null)
            return val;
        if (!negativeCache.contains(key))
            val=lookupMembers(key);
        if (val==null && parentScope!=null)
            val=parentScope.lookup(key);
        return val;
    }
    
    void addMember(final ScopeMember member) {
        positiveCache.clear();
        negativeCache.clear();
        members.add(member);
    }
    
    public boolean equals(Object obj) {
        if (obj!=null && obj instanceof Scope) {
            Scope sc=(Scope)obj;
            if (!members.equals(sc.members))
                return false;
            if (parentScope==null)
                return parentScope==sc.parentScope;
            return parentScope.equals(sc.parentScope);
        }
        return false;
    }
    
    protected Object clone() {
        Scope cloned=new Scope(parentScope);
        
        cloned.members=(ArrayList)members.clone();
        return cloned;
    }
    
    private Object lookupMembers(final Object key) {
        Iterator it=members.iterator();
        Object value=null;
        
        while(it.hasNext()) {
            ScopeMember m=(ScopeMember)it.next();
            Object val=m.lookup(key);
            
            if (val==null)
                continue;
            if (value==null) {
                value=val;
                continue;
            }
            if (!value.equals(val))
                // ambiguos reference
                JMManager.getLog().log("Ambiguos reference "+key+":"+value+":"+val); // NOI18N
        }
        if (value!=null)
            positiveCache.put(key,value);
        else
            negativeCache.add(key);
        return value;
    }
    
    static Scope createMemberTypeScope(ClassDefinition jcls,MDRParser sc) {
        if (jcls instanceof ParameterizedType)
            jcls=((ParameterizedType)jcls).getDefinition();
        if (jcls instanceof UnresolvedClass)
            return new Scope(null);
        if (sc!=null) {
            String id=jcls.refMofId();
            Map cache=sc.getCacheFor(Scope.class.getName()+"createMemberTypeScope"); // NOI18N
            Scope scope=(Scope)cache.get(id);
            
            if (scope==null) {
                cache.put(id,new Scope(null));
                scope=constructMemberTypeScope(jcls, sc);
                cache.put(id,scope);
            }
            return scope;
        }
        return constructMemberTypeScope(jcls, sc);
    }
    
    static Scope constructMemberTypeScope(ClassDefinition jcls,MDRParser sc) {
        List superScopes=new ArrayList(2);
        Scope superScope=null;
        Scope memberScope;
        JavaClass superJavaClass=sc.getSuperClass(jcls);
        Collection interfaces=sc.getSuperInterfaces(jcls);
        Iterator ifaceIt=interfaces.iterator();
        
        if (superJavaClass!=null && !(superJavaClass instanceof UnresolvedClass))
            superScopes.add(createMemberTypeScope(superJavaClass,sc));
        while (ifaceIt.hasNext()) {
            JavaClass ifaceClass=(JavaClass)ifaceIt.next();
            
            if (ifaceClass!=null && !(ifaceClass instanceof UnresolvedClass))
                superScopes.add(createMemberTypeScope(ifaceClass,sc));
        }
        if (!superScopes.isEmpty()) {
            Iterator scopeIt=superScopes.iterator();

            superScope=new Scope(null);
            while(scopeIt.hasNext())
                superScope.addMember((ScopeMember)scopeIt.next());
        }
        memberScope=new Scope(superScope);
        if (jcls instanceof JavaClass)
            memberScope.addMember(new MemberClassScope((JavaClass)jcls));
        return memberScope;
    }
    
    static Scope createTypeScope(String jpck, ClassPath classPath, ElementInfo[] imports) {
        Scope packageImp=new Scope(null);
        Scope currentPackage=new Scope(packageImp);
        Scope singleImp=new Scope(currentPackage);
        Scope memberTypes=new Scope(singleImp);
        Iterator it;
        Resource rsc;
        
        packageImp.addMember(PackageImpScope.createScope("java.lang",classPath)); // NOI18N
        currentPackage.addMember(PackageImpScope.createScope(jpck,classPath));
        if (imports != null) {
            for (int i = 0; i < imports.length; i++) {
                ElementInfo importInfo=imports[i];
                Reference refTree=importInfo.getASTree();
                String name;
                
                if (refTree!=null) {
                    ASTree tree=(ASTree)refTree.get();

                    if (tree.getSubTrees()[0]!=null) // static import
                        continue;
                }
                name=importInfo.name;
                if (importInfo.infoType==ElementInfo.IMPORT_ON_DEMAND_TYPE)
                    packageImp.addMember(PackageImpScope.createScope(name,classPath));
                else
                    singleImp.addMember(new SingleImpScope(name));
            }
        }
        return singleImp;
    }

    static Scope createStaticImpScope(Resource rsc) {
        Scope packageImp=new Scope(null);
        Scope singleImp=new Scope(packageImp);
        Scope memberTypes=new Scope(singleImp);
        Iterator importsIt=rsc.getImports().iterator();
        JavaClassClassImpl jclsClass=(JavaClassClassImpl)((JavaModelPackage)rsc.refImmediatePackage()).getJavaClass();
        
        while(importsIt.hasNext()) {
            Import imp=(Import)importsIt.next();

            if (imp.isStatic()) {
                String name=imp.getName();
                
                if (imp.isOnDemand()) {
                    JavaClass javaClass =(JavaClass)jclsClass.resolveClass(name, true);
                    
                    if (javaClass!=null)
                        packageImp.addMember(new StaticImportScope(javaClass,null));
                } else {
                    int lastDot=name.lastIndexOf('.');
                    
                    if (lastDot!=-1) {
                        String className=name.substring(0,lastDot);
                        JavaClass javaClass =(JavaClass)jclsClass.resolveClass(className, true);
                        
                        if (javaClass!=null)
                            singleImp.addMember(new StaticImportScope(javaClass,name.substring(lastDot+1)));
                    }
                }
            }
        }
        return singleImp;
    }
    
    static MethodScope createMethodScope(ClassDefinition jcls,MDRParser sc) {
        if (jcls instanceof UnresolvedClass)
            return new MethodScope(null);
        if (sc!=null) {
            String id=jcls.refMofId();
            Map cache=sc.getCacheFor(Scope.class.getName()+"createMethodScope"); // NOI18N
            MethodScope scope=(MethodScope)cache.get(id);

            if (scope==null) {
                scope=createMethodScopeImpl(jcls,sc);
                cache.put(id,scope);
            }
            return scope;
        }
        return createMethodScopeImpl(jcls,sc);
    }

    private static MethodScope createMethodScopeImpl(ClassDefinition jcls,MDRParser sc) {
        JavaClass superJavaClass=jcls.getSuperClass();
        Iterator ifaceIt=jcls.getInterfaces().iterator();
        List superScopes=new ArrayList(2);
        Iterator scopeIt;
        MethodScope superScope;
        MethodScope memberScope;
        
        if (superJavaClass!=null)
            superScopes.add(createMethodScope(superJavaClass,sc));
        while (ifaceIt.hasNext()) {
            JavaClass ifaceClass=(JavaClass)ifaceIt.next();
            
            if (ifaceClass!=null)
                superScopes.add(createMethodScope(ifaceClass,sc));
        }
        superScope=new MethodScope(null);
        scopeIt=superScopes.iterator();
        while(scopeIt.hasNext())
            superScope.addMember((ScopeMember)scopeIt.next());
        memberScope=new MethodScope(superScope);
        memberScope.addMember(new MethodScopeMember(jcls));
        return memberScope;
    }

    static Scope createFieldScope(ClassDefinition jcls,MDRParser sc) {
        if (jcls instanceof UnresolvedClass)
            return new Scope(null);
        if (sc!=null) {
            String id=jcls.refMofId();
            Map cache=sc.getCacheFor(Scope.class.getName()+"createFieldScope"); // NOI18N
            Scope scope=(Scope)cache.get(id);
        
            if (scope==null) {
                scope=createFieldScopeImpl(jcls,sc);
                cache.put(id,scope);
            }
            return scope;
        }
        return createFieldScopeImpl(jcls,sc);
    }
        
    private static Scope createFieldScopeImpl(ClassDefinition jcls,MDRParser sc) {
        JavaClass superJavaClass=jcls.getSuperClass();
        Iterator ifaceIt=jcls.getInterfaces().iterator();
        List superScopes=new ArrayList(2);
        Iterator scopeIt;
        Scope superScope;
        Scope memberScope;
        
        if (superJavaClass!=null)
            superScopes.add(createFieldScope(superJavaClass,sc));
        while (ifaceIt.hasNext()) {
            JavaClass ifaceClass=(JavaClass)ifaceIt.next();
            
            if (ifaceClass!=null)
                superScopes.add(createFieldScope(ifaceClass,sc));
        }
        superScope=new Scope(null);
        scopeIt=superScopes.iterator();
        while(scopeIt.hasNext())
            superScope.addMember((ScopeMember)scopeIt.next());
        memberScope=new Scope(superScope);
        memberScope.addMember(new MemberFieldScope(jcls));
        return memberScope;
    }

    public static Scope createTypeScope(Resource rsc,ClassPath classPath) {
        String jpck=rsc.getPackageName();
        Collection importCol=rsc.getImports();
        Iterator it=importCol.iterator();
        List imports=new ArrayList();
        
        while(it.hasNext()) {
            Import imp=(Import)it.next();
            if (!imp.isStatic()) {
                int infoType=imp.isOnDemand()?ElementInfo.IMPORT_ON_DEMAND_TYPE:ElementInfo.SINGLE_IMPORT_TYPE;

                imports.add(new ElementInfo(null, infoType, imp.getName()));
            }
        }
        return createTypeScope(jpck,classPath,(ElementInfo[])imports.toArray(new ElementInfo[imports.size()]));
    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.