com.google.gwt.dev.jjs.SourceOrigin.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gwt.dev.jjs.SourceOrigin.java

Source

/*
 * Copyright 2008 Google Inc.
 * 
 * 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 com.google.gwt.dev.jjs;

import com.google.gwt.dev.jjs.Correlation.Axis;
import com.google.gwt.dev.jjs.CorrelationFactory.DummyCorrelationFactory;
import com.google.gwt.dev.util.StringInterner;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Describes where a SourceInfo's node came from. This class currently includes
 * only physical origin information, but could be extended to provide support
 * for source-Module and -Generators.
 * 
 * TODO: rename this class to make it parallel to {@link SourceInfoCorrelation}?
 * 
 * TODO: make this package-protected?
 */
public class SourceOrigin implements SourceInfo {

    private static class SourceOriginPos extends SourceOrigin {
        private final int endPos;
        private final int startPos;

        private SourceOriginPos(String location, int startLine, int startPos, int endPos) {
            super(location, startLine);
            this.startPos = startPos;
            this.endPos = endPos;
        }

        @Override
        public int getEndPos() {
            return endPos;
        }

        @Override
        public int getStartPos() {
            return startPos;
        }

        // super.equals and hashCode call getStartPos() and getEndPos(),
        // so there is no need to implement them in this subclass
    }

    public static final SourceOrigin UNKNOWN = new SourceOrigin("Unknown", 0) {
        private Object readResolve() {
            return UNKNOWN;
        }
    };

    /**
     * Cache to reuse recently-created origins. This is very useful for JS nodes,
     * since {@link com.google.gwt.dev.js.JsParser} currently only provides line
     * numbers rather than character positions, so we get a lot of reuse there. We
     * get barely any reuse in the Java AST. Synchronized since several threads
     * could operate on it at once during parallel optimization phases.
     */
    private static final Map<SourceOrigin, SourceOrigin> CANONICAL_SOURCE_ORIGINS = Collections
            .synchronizedMap(new LinkedHashMap<SourceOrigin, SourceOrigin>(150, 0.75f, true) {
                @Override
                protected boolean removeEldestEntry(Entry<SourceOrigin, SourceOrigin> eldest) {
                    return size() > 100;
                }
            });

    private static final Correlation[] NO_CORRELATIONS = new Correlation[0];

    /**
     * Creates SourceOrigin nodes.
     */
    public static SourceOrigin create(int startPos, int endPos, int startLine, String fileName) {
        if (startPos < 0 && endPos < 0) {
            return create(startLine, fileName);
        }

        return new SourceOriginPos(fileName, startLine, startPos, endPos);
    }

    /**
     * Creates SourceOrigin nodes. This factory method will attempt to provide
     * canonicalized instances of SourceOrigin objects.
     */
    public static SourceOrigin create(int startLine, String fileName) {

        SourceOrigin newInstance = new SourceOrigin(fileName, startLine);
        SourceOrigin canonical = CANONICAL_SOURCE_ORIGINS.get(newInstance);

        assert canonical == null || (newInstance != canonical && newInstance.equals(canonical));

        if (canonical != null) {
            return canonical;
        } else {
            CANONICAL_SOURCE_ORIGINS.put(newInstance, newInstance);
            return newInstance;
        }
    }

    // TODO: Add Module and Generator tracking
    private final String fileName;
    private final int startLine;

    private SourceOrigin(String location, int startLine) {
        this.fileName = StringInterner.get().intern(location);
        this.startLine = startLine;
    }

    public void addCorrelation(Correlation c) {
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof SourceOrigin)) {
            return false;
        }
        SourceOrigin other = (SourceOrigin) o;
        return startLine == other.startLine && getEndPos() == other.getEndPos()
                && getStartPos() == other.getStartPos() && fileName.equals(other.fileName);
    }

    public Correlation getCorrelation(Axis axis) {
        return null;
    }

    public Correlation[] getCorrelations() {
        return NO_CORRELATIONS;
    }

    public CorrelationFactory getCorrelator() {
        return DummyCorrelationFactory.INSTANCE;
    }

    public int getEndPos() {
        return -1;
    }

    public String getFileName() {
        return fileName;
    }

    public SourceOrigin getOrigin() {
        return this;
    }

    public int getStartLine() {
        return startLine;
    }

    public int getStartPos() {
        return -1;
    }

    @Override
    public int hashCode() {
        return 2 + 13 * fileName.hashCode() + 17 * startLine + 29 * getStartPos() + 31 * getEndPos();
    }

    public SourceInfo makeChild() {
        return this;
    }

    public SourceInfo makeChild(SourceOrigin origin) {
        return origin;
    }

    @Override
    public String toString() {
        return getFileName() + '(' + getStartLine() + ')';
    }
}