Logo Search packages:      
Sourcecode: janino version File versions  Download package

Java.Atom org::codehaus::janino::UnitCompiler::reclassifyName ( Location  location,
Java.Scope  scope,
final String  identifier 
) throws CompileException [inline, private]

JLS 6.5.2.1

Parameters:
location 
scope 
identifier 
Exceptions:
CompileException 

Definition at line 5159 of file UnitCompiler.java.

References org::codehaus::janino::IClass::getDeclaredIClasses(), org::codehaus::janino::IClass::getDeclaredIFields(), and org::codehaus::janino::IClass::getDescriptor().

                              {

        // Determine scope type body declaration, type and compilation unit.
        Java.TypeBodyDeclaration     scopeTBD = null;
        Java.AbstractTypeDeclaration scopeTypeDeclaration = null;
        Java.CompilationUnit         scopeCompilationUnit;
        {
            Java.Scope s = scope;
            while (
                (s instanceof Java.BlockStatement || s instanceof Java.CatchClause)
                && !(s instanceof Java.TypeBodyDeclaration)
            ) s = s.getEnclosingScope();
            if (s instanceof Java.TypeBodyDeclaration) {
                scopeTBD = (Java.TypeBodyDeclaration) s;
                s = s.getEnclosingScope();
            }
            if (s instanceof Java.TypeDeclaration) {
                scopeTypeDeclaration = (Java.AbstractTypeDeclaration) s;
                s = s.getEnclosingScope();
            }
            while (!(s instanceof Java.CompilationUnit)) s = s.getEnclosingScope();
            scopeCompilationUnit = (Java.CompilationUnit) s;
        }

        // 6.5.2.1.BL1

        // 6.5.2.BL1.B1.B1.1 (JLS3: 6.5.2.BL1.B1.B1.1) / 6.5.6.1.1 Local variable.
        // 6.5.2.BL1.B1.B1.2 (JLS3: 6.5.2.BL1.B1.B1.2) / 6.5.6.1.1 Parameter.
        {
            Java.Scope s = scope;
            if (s instanceof Java.BlockStatement) {
                Java.LocalVariable lv = this.findLocalVariable((Java.BlockStatement) s, identifier);
                if (lv != null) {
                    Java.LocalVariableAccess lva = new Java.LocalVariableAccess(location, lv);
                    if (!(scope instanceof Java.BlockStatement)) throw new RuntimeException("SNO: Local variable access in non-block statement context!?");
                    lva.setEnclosingBlockStatement((Java.BlockStatement) scope);
                    return lva;
                }
                s = s.getEnclosingScope();
            }
            while (s instanceof Java.BlockStatement || s instanceof Java.CatchClause) s = s.getEnclosingScope();
            if (s instanceof Java.FunctionDeclarator) {
                s = s.getEnclosingScope();
                if (s instanceof Java.InnerClassDeclaration) {
                    Java.InnerClassDeclaration icd = (Java.InnerClassDeclaration) s;
                    s = s.getEnclosingScope();
                    if (s instanceof Java.AnonymousClassDeclaration) s = s.getEnclosingScope();
                    while (s instanceof Java.BlockStatement) {
                        Java.LocalVariable lv = this.findLocalVariable((Java.BlockStatement) s, identifier);
                        if (lv != null) {
                            if (!lv.finaL) this.compileError("Cannot access non-final local variable \"" + identifier + "\" from inner class");
                            final IClass lvType = lv.type;
                            IClass.IField iField = new SimpleIField(
                                this.resolve(icd),
                                "val$" + identifier,
                                lvType
                            );
                            icd.defineSyntheticField(iField);
                            Java.FieldAccess fa = new Java.FieldAccess(
                                location,                        // location
                                new Java.QualifiedThisReference( // lhs
                                    location,                                        // location
                                    new Java.SimpleType(location, this.resolve(icd)) // qualification
                                ),
                                iField                           // field
                            );
                            fa.setEnclosingBlockStatement((Java.BlockStatement) scope);
                            return fa;
                        }
                        s = s.getEnclosingScope();
                        while (s instanceof Java.BlockStatement) s = s.getEnclosingScope();
                        if (!(s instanceof Java.FunctionDeclarator)) break;
                        s = s.getEnclosingScope();
                        if (!(s instanceof Java.InnerClassDeclaration)) break;
                        icd = (Java.InnerClassDeclaration) s;
                        s = s.getEnclosingScope();
                    }
                }
            }
        }

        // 6.5.2.BL1.B1.B1.3 (JLS3: 6.5.2.BL1.B1.B1.3) / 6.5.6.1.2.1 Field.
        Java.BlockStatement enclosingBlockStatement = null;
        for (Java.Scope s = scope; !(s instanceof Java.CompilationUnit); s = s.getEnclosingScope()) {
            if (s instanceof Java.BlockStatement && enclosingBlockStatement == null) enclosingBlockStatement = (Java.BlockStatement) s;
            if (s instanceof Java.TypeDeclaration) {
                final IClass etd = UnitCompiler.this.resolve((Java.AbstractTypeDeclaration) s);
                final IClass.IField f = this.findIField(etd, identifier, location);
                if (f != null) {
                    if (f.isStatic()) {
                        this.warning("IASF", "Implicit access to static field \"" + identifier + "\" of declaring class (better write \"" + f.getDeclaringIClass() + '.' + f.getName() + "\")", location);
                    } else
                    if (f.getDeclaringIClass() == etd) {
                        this.warning("IANSF", "Implicit access to non-static field \"" + identifier + "\" of declaring class (better write \"this." + f.getName() + "\")", location);
                    } else {
                        this.warning("IANSFEI", "Implicit access to non-static field \"" + identifier + "\" of enclosing instance (better write \"" + f.getDeclaringIClass() + ".this." + f.getName() + "\")", location);
                    }

                    Java.Type ct = new Java.SimpleType(scopeTypeDeclaration.getLocation(), (IClass) etd);
                    Java.Atom lhs;
                    if (scopeTBD.isStatic()) {

                        // Field access in static method context.
                        lhs = ct;
                    } else
                    {

                        // Field access in non-static method context.
                        if (f.isStatic()) {

                            // Access to static field.
                            lhs = ct;
                        } else {

                            // Access to non-static field.
                            lhs = new Java.QualifiedThisReference(location, ct);
                        }
                    }
                    Java.FieldAccess fa = new Java.FieldAccess(
                        location,
                        lhs,
                        f
                    );
                    fa.setEnclosingBlockStatement(enclosingBlockStatement);
                    return fa;
                }
            }
        }

        // JLS3 6.5.2.BL1.B1.B2.1 Static field imported through single static import.
        {
            Object o = this.singleStaticImports.get(identifier);
            if (o instanceof IField) return new FieldAccess(location, new SimpleType(location, ((IField) o).getDeclaringIClass()), (IField) o);
        }

        // JLS3 6.5.2.BL1.B1.B2.2 Static field imported through static-import-on-demand.
        for (Iterator it = this.staticImportsOnDemand.iterator(); it.hasNext();) {
            IClass iClass = (IClass) it.next();
            IField[] flds = iClass.getDeclaredIFields();
            for (int i = 0 ; i < flds.length; ++i) {
                IField f = flds[i];
                if (f.getName().equals(identifier)) return new FieldAccess(location, new SimpleType(location, iClass), f);
            }
        }

        // Hack: "java" MUST be a package, not a class.
        if (identifier.equals("java")) return new Java.Package(location, identifier);

        // 6.5.2.BL1.B1.B2.1 (JLS3: 6.5.2.BL1.B1.B3.2) Local class.
        {
            Java.LocalClassDeclaration lcd = this.findLocalClassDeclaration(scope, identifier);
            if (lcd != null) return new Java.SimpleType(location, this.resolve(lcd));
        }

        // 6.5.2.BL1.B1.B2.2 (JLS3: 6.5.2.BL1.B1.B3.3) Member type.
        if (scopeTypeDeclaration != null) {
            IClass memberType = this.findMemberType(UnitCompiler.this.resolve(scopeTypeDeclaration), identifier, location);
            if (memberType != null) return new Java.SimpleType(location, memberType);
        }

        // 6.5.2.BL1.B1.B3.1 (JLS3: 6.5.2.BL1.B1.B4.1) Single type import.
        if (scopeCompilationUnit != null) {
            IClass iClass = this.importSingleType(identifier, location);
            if (iClass != null) return new Java.SimpleType(location, iClass);
        }

        // 6.5.2.BL1.B1.B3.2 (JLS3: 6.5.2.BL1.B1.B3.1) Package member class/interface declared in this compilation unit.
        // Notice that JLS2 looks this up AFTER local class, member type, single type import, while
        // JLS3 looks this up BEFORE local class, member type, single type import.
        if (scopeCompilationUnit != null) {
            Java.PackageMemberTypeDeclaration pmtd = scopeCompilationUnit.getPackageMemberTypeDeclaration(identifier);
            if (pmtd != null) return new Java.SimpleType(location, this.resolve((Java.AbstractTypeDeclaration) pmtd));
        }

        // 6.5.2.BL1.B1.B4 Class or interface declared in same package.
        // Notice: Why is this missing in JLS3?
        if (scopeCompilationUnit != null) {
            String className = (
                scopeCompilationUnit.optionalPackageDeclaration == null ?
                identifier :
                scopeCompilationUnit.optionalPackageDeclaration.packageName + '.' + identifier
            );
            IClass result;
            try {
                result = this.iClassLoader.loadIClass(Descriptor.fromClassName(className));
            } catch (ClassNotFoundException ex) {
                if (ex.getException() instanceof CompileException) throw (CompileException) ex.getException();
                throw new CompileException(className, location, ex);
            }
            if (result != null) return new Java.SimpleType(location, result);
        }

        // 6.5.2.BL1.B1.B5 (JLS3: 6.5.2.BL1.B1.B4.2), 6.5.2.BL1.B1.B6 Type-import-on-demand.
        if (scopeCompilationUnit != null) {
            IClass importedClass = this.importTypeOnDemand(identifier, location);
            if (importedClass != null) {
                return new Java.SimpleType(location, importedClass);
            }
        }

        // JLS3 6.5.2.BL1.B1.B4.3 Type imported through single static import.
        {
            Object o = this.singleStaticImports.get(identifier);
            if (o instanceof IClass) return new SimpleType(null, (IClass) o);
        }

        // JLS3 6.5.2.BL1.B1.B4.4 Type imported through static-import-on-demand.
        {
            for (Iterator it = this.staticImportsOnDemand.iterator(); it.hasNext();) {
                IClass ic = (IClass) it.next();
                IClass[] memberTypes = ic.getDeclaredIClasses();
                for (int i = 0; i < memberTypes.length; ++i) {
                    IClass mt = memberTypes[i];
                    if (mt.getDescriptor().endsWith('$' + identifier + ';')) return new Java.SimpleType(null, mt);
                }
            }
        }
        
        // 6.5.2.BL1.B1.B7 Package name
        return new Java.Package(location, identifier);
    }


Generated by  Doxygen 1.6.0   Back to index